netdev: Add argument to netdev_open() to specify Ethernet type to capture.
authorBen Pfaff <blp@nicira.com>
Mon, 14 Jul 2008 20:03:19 +0000 (13:03 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 18 Jul 2008 20:42:38 +0000 (13:42 -0700)
This is needed by the controller, which wants to listen only for
OpenFlow discovery BPDUs on its network devices.

Also, update all existing callers.

include/netdev.h
lib/netdev.c
secchan/secchan.c
switch/datapath.c

index 06476e2ee24f9fa3448095fcb017485832e00eb4..57b7cbd46542f455daff0d643ec2cd624cb114df 100644 (file)
@@ -52,8 +52,14 @@ enum netdev_flags {
     NETDEV_PROMISC = 0x0002     /* Promiscuous mode? */
 };
 
+enum netdev_pseudo_ethertype {
+    NETDEV_ETH_TYPE_NONE = -128, /* Receive no frames. */
+    NETDEV_ETH_TYPE_ANY,         /* Receive all frames. */
+    NETDEV_ETH_TYPE_802_2        /* Receive all IEEE 802.2 frames. */
+};
+
 struct netdev;
-int netdev_open(const char *name, struct netdev **);
+int netdev_open(const char *name, int ethertype, struct netdev **);
 void netdev_close(struct netdev *);
 int netdev_recv(struct netdev *, struct buffer *);
 void netdev_recv_wait(struct netdev *);
index 43592393839ac5d867e41d69dc6cfcdfeacb0a11..a96f782cd1bb6d08ab2f44e7aced084808172e94 100644 (file)
@@ -209,9 +209,14 @@ do_ethtool(struct netdev *netdev)
 
 /* Opens the network device named 'name' (e.g. "eth0") and returns zero if
  * successful, otherwise a positive errno value.  On success, sets '*netdev'
- * to the new network device, otherwise to null. */
+ * to the new network device, otherwise to null.
+ *
+ * 'ethertype' may be a 16-bit Ethernet protocol value in host byte order to
+ * capture frames of that type received on the device.  It may also be one of
+ * the 'enum netdev_pseudo_ethertype' values to receive frames in one of those
+ * categories. */
 int
-netdev_open(const char *name, struct netdev **netdev_)
+netdev_open(const char *name, int ethertype, struct netdev **netdev_)
 {
     int fd;
     struct sockaddr sa;
@@ -234,7 +239,11 @@ netdev_open(const char *name, struct netdev **netdev_)
      * We have to use SOCK_PACKET, despite its deprecation, because only
      * SOCK_PACKET lets us set the hardware source address of outgoing
      * packets. */
-    fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL));
+    fd = socket(PF_PACKET, SOCK_PACKET,
+                htons(ethertype == NETDEV_ETH_TYPE_NONE ? 0
+                      : ethertype == NETDEV_ETH_TYPE_ANY ? ETH_P_ALL
+                      : ethertype == NETDEV_ETH_TYPE_802_2 ? ETH_P_802_2
+                      : ethertype));
     if (fd < 0) {
         return errno;
     }
index 8c59b8aea7a6dd7c0efc2f3acd1ae4ee11970dbb..80ba987018e4c9005a299d0713754d53a48b57fa 100644 (file)
@@ -166,7 +166,7 @@ main(int argc, char *argv[])
     }
 
     snprintf(of_name, sizeof of_name, "of%s", nl_name + 3);
-    retval = netdev_open(of_name, &of_device);
+    retval = netdev_open(of_name, NETDEV_ETH_TYPE_NONE, &of_device);
     if (!retval) {
         enum netdev_flags flags;
         retval = netdev_get_flags(of_device, &flags);
index a196bead29cceb7d8995458634ddb86275cf4393..a7e5d9382f0d8ac68728111511c74e74e9a08d08 100644 (file)
@@ -215,7 +215,7 @@ dp_add_port(struct datapath *dp, const char *name)
     struct sw_port *p;
     int error;
 
-    error = netdev_open(name, &netdev);
+    error = netdev_open(name, NETDEV_ETH_TYPE_ANY, &netdev);
     if (error) {
         return error;
     }