keep "kernel name" for each netdev
authorYAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Tue, 21 May 2013 08:49:55 +0000 (17:49 +0900)
committerBen Pfaff <blp@nicira.com>
Thu, 23 May 2013 03:51:22 +0000 (20:51 -0700)
where interface renaming is not supported (NetBSD), remember both of
our netdev name and the correspoinding kernel name separately.
the latter is necessary to talk with kernel using interface names.
eg. ifioctls, bpf

XXX there should be a proper way to query kernel name.
Ben Pfaff suggested ovs-appctl but this patch doesn't implement it. (yet)

Signed-off-by: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/netdev-bsd.c

index eb45563..a5b7c93 100644 (file)
@@ -88,6 +88,8 @@ struct netdev_bsd {
     /* Used for sending packets on non-tap devices. */
     pcap_t *pcap;
     int fd;
+
+    char *kernel_name;
 };
 
 
@@ -159,6 +161,12 @@ netdev_rx_bsd_cast(const struct netdev_rx *rx)
     return CONTAINER_OF(rx, struct netdev_rx_bsd, up);
 }
 
+static const char *
+netdev_get_kernel_name(const struct netdev *netdev)
+{
+    return netdev_bsd_cast(netdev)->kernel_name;
+}
+
 /* Initialize the AF_INET socket used for ioctl operations */
 static int
 netdev_bsd_init(void)
@@ -291,6 +299,7 @@ netdev_bsd_create_system(const struct netdev_class *class, const char *name,
     netdev->change_seq = 1;
     netdev_init(&netdev->up, name, class);
     netdev->tap_fd = -1;
+    netdev->kernel_name = xstrdup(name);
 
     /* Verify that the netdev really exists by attempting to read its flags */
     error = netdev_get_flags(&netdev->up, &flags);
@@ -315,6 +324,7 @@ netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
     struct netdev_bsd *netdev = NULL;
     int error = 0;
     struct ifreq ifr;
+    char *kernel_name = NULL;
 
     error = cache_notifier_ref();
     if (error) {
@@ -351,34 +361,35 @@ netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
         destroy_tap(netdev->tap_fd, ifr.ifr_name);
         goto error_undef_notifier;
     }
+    kernel_name = xstrdup(name);
 #else
     /*
-     * XXX
      * NetBSD doesn't support inteface renaming.
      */
     VLOG_INFO("tap %s is created for bridge %s", ifr.ifr_name, name);
-    name = ifr.ifr_name; /* XXX */
+    kernel_name = xstrdup(ifr.ifr_name);
 #endif
 
     /* set non-blocking. */
     error = set_nonblocking(netdev->tap_fd);
     if (error) {
-        destroy_tap(netdev->tap_fd, name);
+        destroy_tap(netdev->tap_fd, kernel_name);
         goto error_undef_notifier;
     }
 
     /* Turn device UP */
     ifr_set_flags(&ifr, IFF_UP);
-    strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+    strncpy(ifr.ifr_name, kernel_name, sizeof ifr.ifr_name);
     if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) == -1) {
         error = errno;
-        destroy_tap(netdev->tap_fd, name);
+        destroy_tap(netdev->tap_fd, kernel_name);
         goto error_undef_notifier;
     }
 
     /* initialize the device structure and
      * link the structure to its netdev */
     netdev_init(&netdev->up, name, class);
+    netdev->kernel_name = kernel_name;
     *netdevp = &netdev->up;
 
     return 0;
@@ -387,6 +398,7 @@ error_undef_notifier:
     cache_notifier_unref();
 error:
     free(netdev);
+    free(kernel_name);
     return error;
 }
 
@@ -398,11 +410,12 @@ netdev_bsd_destroy(struct netdev *netdev_)
     cache_notifier_unref();
 
     if (netdev->tap_fd >= 0) {
-        destroy_tap(netdev->tap_fd, netdev_get_name(netdev_));
+        destroy_tap(netdev->tap_fd, netdev_get_kernel_name(netdev_));
     }
     if (netdev->pcap) {
         pcap_close(netdev->pcap);
     }
+    free(netdev->kernel_name);
     free(netdev);
 }
 
@@ -488,7 +501,8 @@ netdev_bsd_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
         pcap = NULL;
         fd = netdev->tap_fd;
     } else {
-        int error = netdev_bsd_open_pcap(netdev_get_name(netdev_), &pcap, &fd);
+        int error = netdev_bsd_open_pcap(netdev_get_kernel_name(netdev_),
+                                         &pcap, &fd);
         if (error) {
             return error;
         }
@@ -641,7 +655,7 @@ netdev_rx_bsd_drain(struct netdev_rx *rx_)
     struct ifreq ifr;
     struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
 
-    strcpy(ifr.ifr_name, netdev_rx_get_name(rx_));
+    strcpy(ifr.ifr_name, netdev_get_kernel_name(netdev_rx_get_netdev(rx_)));
     if (ioctl(rx->fd, BIOCFLUSH, &ifr) == -1) {
         VLOG_DBG_RL(&rl, "%s: ioctl(BIOCFLUSH) failed: %s",
                     netdev_rx_get_name(rx_), strerror(errno));
@@ -726,8 +740,8 @@ netdev_bsd_set_etheraddr(struct netdev *netdev_,
 
     if (!(netdev->cache_valid & VALID_ETHERADDR)
         || !eth_addr_equals(netdev->etheraddr, mac)) {
-        error = set_etheraddr(netdev_get_name(netdev_), AF_LINK, ETH_ADDR_LEN,
-                              mac);
+        error = set_etheraddr(netdev_get_kernel_name(netdev_), AF_LINK,
+                              ETH_ADDR_LEN, mac);
         if (!error) {
             netdev->cache_valid |= VALID_ETHERADDR;
             memcpy(netdev->etheraddr, mac, ETH_ADDR_LEN);
@@ -750,7 +764,7 @@ netdev_bsd_get_etheraddr(const struct netdev *netdev_,
     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
 
     if (!(netdev->cache_valid & VALID_ETHERADDR)) {
-        int error = get_etheraddr(netdev_get_name(netdev_),
+        int error = get_etheraddr(netdev_get_kernel_name(netdev_),
                                   netdev->etheraddr);
         if (error) {
             return error;
@@ -776,8 +790,8 @@ netdev_bsd_get_mtu(const struct netdev *netdev_, int *mtup)
         struct ifreq ifr;
         int error;
 
-        error = netdev_bsd_do_ioctl(netdev_get_name(netdev_), &ifr, SIOCGIFMTU,
-                                    "SIOCGIFMTU");
+        error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
+                                    SIOCGIFMTU, "SIOCGIFMTU");
         if (error) {
             return error;
         }
@@ -807,7 +821,8 @@ netdev_bsd_get_carrier(const struct netdev *netdev_, bool *carrier)
         struct ifmediareq ifmr;
 
         memset(&ifmr, 0, sizeof(ifmr));
-        strncpy(ifmr.ifm_name, netdev_get_name(netdev_), sizeof ifmr.ifm_name);
+        strncpy(ifmr.ifm_name, netdev_get_kernel_name(netdev_),
+                sizeof ifmr.ifm_name);
 
         if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
             VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
@@ -1058,7 +1073,7 @@ netdev_bsd_get_in4(const struct netdev *netdev_, struct in_addr *in4,
         int error;
 
         ifr.ifr_addr.sa_family = AF_INET;
-        error = netdev_bsd_do_ioctl(netdev_get_name(netdev_), &ifr,
+        error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
                                     SIOCGIFADDR, "SIOCGIFADDR");
         if (error) {
             return error;
@@ -1067,7 +1082,7 @@ netdev_bsd_get_in4(const struct netdev *netdev_, struct in_addr *in4,
         sin = (struct sockaddr_in *) &ifr.ifr_addr;
         netdev->in4 = sin->sin_addr;
         netdev->cache_valid |= VALID_IN4;
-        error = netdev_bsd_do_ioctl(netdev_get_name(netdev_), &ifr,
+        error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
                                     SIOCGIFNETMASK, "SIOCGIFNETMASK");
         if (error) {
             return error;
@@ -1157,7 +1172,8 @@ do_set_addr(struct netdev *netdev,
 {
     struct ifreq ifr;
     make_in4_sockaddr(&ifr.ifr_addr, addr);
-    return netdev_bsd_do_ioctl(netdev, &ifr, ioctl_nr, ioctl_name);
+    return netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev), &ifr, ioctl_nr,
+                               ioctl_name);
 }
 
 static int
@@ -1202,7 +1218,7 @@ netdev_bsd_update_flags(struct netdev *netdev_, enum netdev_flags off,
         *old_flagsp = iff_to_nd_flags(old_flags);
         new_flags = (old_flags & ~nd_to_iff_flags(off)) | nd_to_iff_flags(on);
         if (new_flags != old_flags) {
-            error = set_flags(netdev_get_name(netdev_), new_flags);
+            error = set_flags(netdev_get_kernel_name(netdev_), new_flags);
             netdev_bsd_changed(netdev);
         }
     }
@@ -1351,7 +1367,7 @@ get_flags(const struct netdev *netdev, int *flags)
     struct ifreq ifr;
     int error;
 
-    error = netdev_bsd_do_ioctl(netdev->name, &ifr,
+    error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev), &ifr,
                                 SIOCGIFFLAGS, "SIOCGIFFLAGS");
 
     *flags = ifr_get_flags(&ifr);