mirror of
https://github.com/openvswitch/ovs
synced 2025-09-03 15:55:19 +00:00
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.
This commit is contained in:
@@ -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;
|
||||
|
@@ -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 *);
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user