mac-learning: Change 'port' member to a union.
authorBen Pfaff <blp@nicira.com>
Fri, 18 Mar 2011 22:03:24 +0000 (15:03 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 22 Mar 2011 16:52:39 +0000 (09:52 -0700)
This allow the client a little more flexibility.  The next commit shows
how this can be useful.

lib/learning-switch.c
lib/mac-learning.h
ofproto/ofproto.c
vswitchd/bridge.c

index 5fa3a53b0249e2447850a420e2d91a03fb3a259f..97aaf9fe50c576270d9a32c905f77734c6cfd9fb 100644 (file)
@@ -326,12 +326,12 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow)
     /* Learn the source MAC. */
     if (mac_learning_may_learn(sw->ml, flow->dl_src, 0)) {
         struct mac_entry *mac = mac_learning_insert(sw->ml, flow->dl_src, 0);
-        if (mac_entry_is_new(mac) || mac->port != flow->in_port) {
+        if (mac_entry_is_new(mac) || mac->port.i != flow->in_port) {
             VLOG_DBG_RL(&rl, "%016llx: learned that "ETH_ADDR_FMT" is on "
                         "port %"PRIu16, sw->datapath_id,
                         ETH_ADDR_ARGS(flow->dl_src), flow->in_port);
 
-            mac->port = flow->in_port;
+            mac->port.i = flow->in_port;
             mac_learning_changed(sw->ml, mac);
         }
     }
@@ -347,7 +347,7 @@ lswitch_choose_destination(struct lswitch *sw, const struct flow *flow)
 
         mac = mac_learning_lookup(sw->ml, flow->dl_dst, 0, NULL);
         if (mac) {
-            out_port = mac->port;
+            out_port = mac->port.i;
             if (out_port == flow->in_port) {
                 /* Don't send a packet back out its input port. */
                 return OFPP_NONE;
index c5c94bb3d39aaea29de34a990c8e098e5c4f0c4a..2bff465680d252f7abede682fdd5083bd6d434e0 100644 (file)
@@ -44,8 +44,12 @@ struct mac_entry {
     time_t grat_arp_lock;       /* Gratuitous ARP lock expiration time. */
     uint8_t mac[ETH_ADDR_LEN];  /* Known MAC address. */
     uint16_t vlan;              /* VLAN tag. */
-    int port;                   /* Port on which MAC was most recently seen. */
     tag_type tag;               /* Tag for this learning entry. */
+
+    /* Learned port. */
+    union {
+        int i;
+    } port;
 };
 
 int mac_entry_age(const struct mac_entry *);
index fea9119699dcd7a7d6f28f6acf66bfc8bf6dd84e..6f2b43cae9a9ca4bf7b4b7e20afb9fb498635eac 100644 (file)
@@ -5275,7 +5275,7 @@ default_normal_ofhook_cb(const struct flow *flow, const struct ofpbuf *packet,
         struct mac_entry *src_mac;
 
         src_mac = mac_learning_insert(ofproto->ml, flow->dl_src, 0);
-        if (mac_entry_is_new(src_mac) || src_mac->port != flow->in_port) {
+        if (mac_entry_is_new(src_mac) || src_mac->port.i != flow->in_port) {
             /* The log messages here could actually be useful in debugging,
              * so keep the rate limit relatively high. */
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
@@ -5284,7 +5284,7 @@ default_normal_ofhook_cb(const struct flow *flow, const struct ofpbuf *packet,
 
             ofproto_revalidate(ofproto,
                                mac_learning_changed(ofproto->ml, src_mac));
-            src_mac->port = flow->in_port;
+            src_mac->port.i = flow->in_port;
         }
     }
 
@@ -5294,7 +5294,7 @@ default_normal_ofhook_cb(const struct flow *flow, const struct ofpbuf *packet,
         flood_packets(ofproto, flow->in_port, OFPPC_NO_FLOOD,
                       nf_output_iface, odp_actions);
     } else {
-        int out_port = dst_mac->port;
+        int out_port = dst_mac->port.i;
         if (out_port != flow->in_port) {
             nl_msg_put_u32(odp_actions, ODP_ACTION_ATTR_OUTPUT, out_port);
             *nf_output_iface = out_port;
index 0bb9cc22c37917a1ece36990496aa71d5b06b1f8..cdce56ba23e66d64194651969a99a947573d5884 100644 (file)
@@ -1517,11 +1517,11 @@ bridge_unixctl_fdb_show(struct unixctl_conn *conn,
 
     ds_put_cstr(&ds, " port  VLAN  MAC                Age\n");
     LIST_FOR_EACH (e, lru_node, &br->ml->lrus) {
-        if (e->port < 0 || e->port >= br->n_ports) {
+        if (e->port.i < 0 || e->port.i >= br->n_ports) {
             continue;
         }
         ds_put_format(&ds, "%5d  %4d  "ETH_ADDR_FMT"  %3d\n",
-                      port_get_an_iface(br->ports[e->port])->dp_ifidx,
+                      port_get_an_iface(br->ports[e->port.i])->dp_ifidx,
                       e->vlan, ETH_ADDR_ARGS(e->mac), mac_entry_age(e));
     }
     unixctl_command_reply(conn, 200, ds_cstr(&ds));
@@ -2787,7 +2787,7 @@ update_learning_table(struct bridge *br, const struct flow *flow, int vlan,
         }
     }
 
-    if (mac_entry_is_new(mac) || mac->port != in_port->port_idx) {
+    if (mac_entry_is_new(mac) || mac->port.i != in_port->port_idx) {
         /* The log messages here could actually be useful in debugging,
          * so keep the rate limit relatively high. */
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
@@ -2796,7 +2796,7 @@ update_learning_table(struct bridge *br, const struct flow *flow, int vlan,
                     br->name, ETH_ADDR_ARGS(flow->dl_src),
                     in_port->name, vlan);
 
-        mac->port = in_port->port_idx;
+        mac->port.i = in_port->port_idx;
         ofproto_revalidate(br->ofproto, mac_learning_changed(br->ml, mac));
     }
 }
@@ -2902,7 +2902,7 @@ is_admissible(struct bridge *br, const struct flow *flow, bool have_packet,
          * reflections on bond slaves.  If this is the case, just drop the
          * packet now. */
         mac = mac_learning_lookup(br->ml, flow->dl_src, vlan, NULL);
-        if (mac && mac->port != in_port->port_idx &&
+        if (mac && mac->port.i != in_port->port_idx &&
             (!is_gratuitous_arp(flow) || mac_entry_is_grat_arp_locked(mac))) {
                 return false;
         }
@@ -2937,8 +2937,8 @@ process_flow(struct bridge *br, const struct flow *flow,
 
     /* Determine output port. */
     mac = mac_learning_lookup(br->ml, flow->dl_dst, vlan, tags);
-    if (mac && mac->port >= 0 && mac->port < br->n_ports) {
-        out_port = br->ports[mac->port];
+    if (mac && mac->port.i >= 0 && mac->port.i < br->n_ports) {
+        out_port = br->ports[mac->port.i];
     } else if (!packet && !eth_addr_is_multicast(flow->dl_dst)) {
         /* If we are revalidating but don't have a learning entry then
          * eject the flow.  Installing a flow that floods packets opens
@@ -3425,7 +3425,7 @@ bond_send_learning_packets(struct port *port)
         struct flow flow;
         int retval;
 
-        if (e->port == port->port_idx) {
+        if (e->port.i == port->port_idx) {
             continue;
         }
 
@@ -3601,7 +3601,7 @@ bond_unixctl_show(struct unixctl_conn *conn,
 
                 memcpy(flow.dl_src, me->mac, ETH_ADDR_LEN);
                 if (bond_hash_src(me->mac, me->vlan) == hash
-                    && me->port != port->port_idx
+                    && me->port.i != port->port_idx
                     && choose_output_iface(port, &flow, me->vlan,
                                            &dp_ifidx, &tags)
                     && dp_ifidx == iface->dp_ifidx)