X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fin-band.c;fp=secchan%2Fin-band.c;h=18415f48efb5a5bcc308bc62a73b6bac26202fda;hb=f1acd62b54376a425a975f9af501c4c8c5689b39;hp=fa77a254d73abcb25675cdd22c1ac78aa2cd4625;hpb=0ad9b732910b8f1aa7fc47ea57ff79e7618a4e6d;p=sliver-openvswitch.git diff --git a/secchan/in-band.c b/ofproto/in-band.c similarity index 86% rename from secchan/in-band.c rename to ofproto/in-band.c index fa77a254d..18415f48e 100644 --- a/secchan/in-band.c +++ b/ofproto/in-band.c @@ -75,12 +75,13 @@ struct in_band { /* Keep track of local port's information. */ uint8_t local_mac[ETH_ADDR_LEN]; /* Current MAC. */ - char local_name[IF_NAMESIZE]; /* Local device name. */ + struct netdev *local_netdev; /* Local port's network device. */ time_t next_local_refresh; /* Keep track of controller and next hop's information. */ uint32_t controller_ip; /* Controller IP, 0 if unknown. */ uint8_t remote_mac[ETH_ADDR_LEN]; /* Remote MAC. */ + struct netdev *remote_netdev; uint8_t last_remote_mac[ETH_ADDR_LEN]; /* Previous remote MAC. */ time_t next_remote_refresh; @@ -95,14 +96,17 @@ get_remote_mac(struct in_band *ib) { int retval; bool have_mac; - struct in_addr c_in4, r_in4; - char *dev_name; + struct in_addr c_in4; /* Controller's IP address. */ + struct in_addr r_in4; /* Next hop IP address. */ + char *next_hop_dev; time_t now = time_now(); if (now >= ib->next_remote_refresh) { + /* Find the next-hop IP address. */ c_in4.s_addr = ib->controller_ip; memset(ib->remote_mac, 0, sizeof ib->remote_mac); - retval = netdev_get_next_hop(&c_in4, &r_in4, &dev_name); + retval = netdev_get_next_hop(ib->local_netdev, + &c_in4, &r_in4, &next_hop_dev); if (retval) { VLOG_WARN("cannot find route for controller ("IP_FMT"): %s", IP_ARGS(&ib->controller_ip), strerror(retval)); @@ -113,17 +117,34 @@ get_remote_mac(struct in_band *ib) r_in4.s_addr = c_in4.s_addr; } - retval = netdev_nodev_arp_lookup(dev_name, r_in4.s_addr, - ib->remote_mac); + /* Get the next-hop IP and network device. */ + if (!ib->remote_netdev + || strcmp(netdev_get_name(ib->remote_netdev), next_hop_dev)) + { + netdev_close(ib->remote_netdev); + retval = netdev_open(next_hop_dev, NETDEV_ETH_TYPE_NONE, + &ib->remote_netdev); + if (retval) { + VLOG_WARN_RL(&rl, "cannot open netdev %s (next hop " + "to controller "IP_FMT"): %s", + next_hop_dev, IP_ARGS(&ib->controller_ip), + strerror(retval)); + ib->next_remote_refresh = now + 1; + return NULL; + } + } + + /* Look up the MAC address of the next-hop IP address. */ + retval = netdev_arp_lookup(ib->remote_netdev, r_in4.s_addr, + ib->remote_mac); if (retval) { VLOG_DBG_RL(&rl, "cannot look up remote MAC address ("IP_FMT"): %s", IP_ARGS(&r_in4.s_addr), strerror(retval)); } have_mac = !eth_addr_is_zero(ib->remote_mac); - free(dev_name); - - if (have_mac - && !eth_addr_equals(ib->last_remote_mac, ib->remote_mac)) { + free(next_hop_dev); + if (have_mac + && !eth_addr_equals(ib->last_remote_mac, ib->remote_mac)) { VLOG_DBG("remote MAC address changed from "ETH_ADDR_FMT" to " ETH_ADDR_FMT, ETH_ADDR_ARGS(ib->last_remote_mac), @@ -149,7 +170,7 @@ get_local_mac(struct in_band *ib) time_t now = time_now(); if (now >= ib->next_local_refresh) { uint8_t ea[ETH_ADDR_LEN]; - if (!netdev_nodev_get_etheraddr(ib->local_name, ea)) { + if (ib->local_netdev && netdev_get_etheraddr(ib->local_netdev, ea)) { memcpy(ib->local_mac, ea, ETH_ADDR_LEN); } ib->next_local_refresh = now + 1; @@ -428,30 +449,44 @@ in_band_flushed(struct in_band *in_band) } } -void +int in_band_create(struct ofproto *ofproto, struct dpif *dpif, struct switch_status *ss, struct rconn *controller, struct in_band **in_bandp) { struct in_band *in_band; + char local_name[IF_NAMESIZE]; + struct netdev *local_netdev; int error; - in_band = xcalloc(1, sizeof *in_band); - error = dpif_port_get_name(dpif, ODPP_LOCAL, in_band->local_name, - sizeof in_band->local_name); + error = dpif_port_get_name(dpif, ODPP_LOCAL, + local_name, sizeof local_name); if (error) { - free(in_band); - return; + VLOG_ERR("failed to initialize in-band control: cannot get name " + "of datapath local port (%s)", strerror(error)); + return error; } + error = netdev_open(local_name, NETDEV_ETH_TYPE_NONE, &local_netdev); + if (error) { + VLOG_ERR("failed to initialize in-band control: cannot open " + "datapath local port %s (%s)", local_name, strerror(error)); + return error; + } + + in_band = xcalloc(1, sizeof *in_band); in_band->ofproto = ofproto; in_band->controller = controller; in_band->ss_cat = switch_status_register(ss, "in-band", in_band_status_cb, in_band); - in_band->next_remote_refresh = TIME_MIN; + in_band->local_netdev = local_netdev; in_band->next_local_refresh = TIME_MIN; + in_band->remote_netdev = NULL; + in_band->next_remote_refresh = TIME_MIN; *in_bandp = in_band; + + return 0; } void @@ -459,6 +494,8 @@ in_band_destroy(struct in_band *in_band) { if (in_band) { switch_status_unregister(in_band->ss_cat); + netdev_close(in_band->local_netdev); + netdev_close(in_band->remote_netdev); /* We don't own the rconn. */ } }