From 1bfe968160d7cc030e44481ba3a2ac68824c2869 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 18 Mar 2011 15:03:24 -0700 Subject: [PATCH] mac-learning: Change 'port' member to a union. This allow the client a little more flexibility. The next commit shows how this can be useful. --- lib/learning-switch.c | 6 +++--- lib/mac-learning.h | 6 +++++- ofproto/ofproto.c | 6 +++--- vswitchd/bridge.c | 18 +++++++++--------- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 5fa3a53b..97aaf9fe 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -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; diff --git a/lib/mac-learning.h b/lib/mac-learning.h index c5c94bb3..2bff4656 100644 --- a/lib/mac-learning.h +++ b/lib/mac-learning.h @@ -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 *); diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index fea91196..6f2b43ca 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -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; diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 0bb9cc22..cdce56ba 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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) -- 2.30.2