diff options
author | Sanjay Sane <ssane@nicira.com> | 2011-08-09 11:08:27 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2011-08-10 09:28:43 -0700 |
commit | 46a33c0334d9b64f8485092661fd32d8d4285fbf (patch) | |
tree | 031f1b3fb62a3b0b34602600c4cbf125691fa60a | |
parent | 5c053952bc2201d3429b49fcb2fe7dc313079b31 (diff) | |
download | openvswitch-46a33c0334d9b64f8485092661fd32d8d4285fbf.tar.gz |
Option to forward BPDU (Ethernet control class) frames
Currently, a NORMAL action bridge drops reserved-multicast-mac addresses;
01-80-c2-00-00-[f0:ff]. A node that does not implement STP should have an
option to forward such frames.
This commit proposes to have a configuration option to allow forwarding of
BPDU class frames. To ensure backward compatibility, this option is
disabled by default.
This config can be set using bridge's other-config column, for e.g
ovs-vsctl set bridge br0 other-config:forward-bpdu=true
Changing this option can revalidate all flows in a software-OVS
implementation (ofproto-dpif)
--------
unit tests:
------------
make config changes, test runtime behavior
-- test runtime behavior --
continuously send packets to br0 with dest-mac=01:80:c2:00:00:00
ovs-dpctl dump-flows br0
ovs-vsctl set bridge br0 other-config:forward-bpdu=true
ovs-dpctl dump-flows br0
ovs-vsctl set bridge br0 other-config:forward-bpdu=false
ovs-dpctl dump-flows br0
ovs-vsctl set bridge br0 other-config:forward-bpdu=true
ovs-dpctl dump-flows br0
ovs-vsctl remove bridge br0 other-config forward-bpdu=true
ovs-dpctl dump-flows br0
--result--
ovs-dpctl dump-flows br0
in_port(1),eth(src=00:0c:29:d1:39:42,dst=01:80:c2:00:00:00), packets:29550, bytes:1773000, used:0.004s, actions:drop
ovs-vsctl set bridge br0 other-config:forward-bpdu=true
ovs-dpctl dump-flows br0
in_port(1),eth(src=00:0c:29:d1:39:42,dst=01:80:c2:00:00:00), packets:8209, bytes:492540, used:0.000s, actions:2,0
ovs-vsctl set bridge br0 other-config:forward-bpdu=false
ovs-dpctl dump-flows br0
in_port(1),eth(src=00:0c:29:d1:39:42,dst=01:80:c2:00:00:00), packets:19, bytes:1140, used:0.000s, actions:drop
ovs-vsctl set bridge br0 other-config:forward-bpdu=true
ovs-dpctl dump-flows br0
in_port(1),eth(src=00:0c:29:d1:39:42,dst=01:80:c2:00:00:00), packets:29, bytes:1740, used:0.000s, actions:2,0
ovs-vsctl remove bridge br0 other-config forward-bpdu=true
ovs-dpctl dump-flows br0
in_port(1),eth(src=00:0c:29:d1:39:42,dst=01:80:c2:00:00:00), packets:0, bytes:0, used:never, actions:drop
Bug #6624
Reported-by: Niklas Andersson <nandersson@nicira.com>
-rw-r--r-- | AUTHORS | 2 | ||||
-rw-r--r-- | ofproto/ofproto-dpif.c | 15 | ||||
-rw-r--r-- | ofproto/ofproto-provider.h | 6 | ||||
-rw-r--r-- | ofproto/ofproto.c | 16 | ||||
-rw-r--r-- | ofproto/ofproto.h | 1 | ||||
-rw-r--r-- | vswitchd/bridge.c | 16 | ||||
-rw-r--r-- | vswitchd/vswitch.xml | 10 |
7 files changed, 64 insertions, 2 deletions
@@ -29,6 +29,7 @@ Pravin B Shelar pshelar@nicira.com Reid Price reid@nicira.com Romain Lenglet romain.lenglet@berabera.info Sajjad Lateef slateef@nicira.com +Sanjay Sane ssane@nicira.com Shih-Hao Li shli@nicira.com Simon Horman horms@verge.net.au Tetsuo NAKAGAWA nakagawa@mxc.nes.nec.co.jp @@ -76,6 +77,7 @@ Krishna Miriyala krishna@nicira.com Luiz Henrique Ozaki luiz.ozaki@gmail.com Michael Mao mmao@nicira.com Mikael Doverhag mdoverhag@nicira.com +Niklas Andersson nandersson@nicira.com Pankaj Thakkar thakkar@nicira.com Paulo Cravero pcravero@as2594.net Peter Balland peter@nicira.com diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index cdc21bca6..633d0d44e 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1393,6 +1393,14 @@ is_mirror_output_bundle(struct ofproto *ofproto_, void *aux) struct ofbundle *bundle = bundle_lookup(ofproto, aux); return bundle && bundle->mirror_out != 0; } + +static void +forward_bpdu_changed(struct ofproto *ofproto_) +{ + struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); + /* Revalidate cached flows whenever forward_bpdu option changes. */ + ofproto->need_revalidate = true; +} /* Ports. */ @@ -3735,8 +3743,10 @@ is_admissible(struct ofproto_dpif *ofproto, const struct flow *flow, return false; } - /* Drop frames for reserved multicast addresses. */ - if (eth_addr_is_reserved(flow->dl_dst)) { + /* Drop frames for reserved multicast addresses + * only if forward_bpdu option is absent. */ + if (eth_addr_is_reserved(flow->dl_dst) && + !ofproto->up.forward_bpdu) { return false; } @@ -4133,4 +4143,5 @@ const struct ofproto_class ofproto_dpif_class = { mirror_set, set_flood_vlans, is_mirror_output_bundle, + forward_bpdu_changed, }; diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index be1e4de6c..c0b3ee97a 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -41,6 +41,8 @@ struct ofproto { unsigned flow_eviction_threshold; /* Threshold at which to begin flow * table eviction. Only affects the * ofproto-dpif implementation */ + bool forward_bpdu; /* Option to allow forwarding of BPDU frames + * when NORMAL action is invoked. */ char *mfr_desc; /* Manufacturer. */ char *hw_desc; /* Hardware. */ char *sw_desc; /* Software version. */ @@ -914,6 +916,10 @@ struct ofproto_class { /* Returns true if 'aux' is a registered bundle that is currently in use as * the output for a mirror. */ bool (*is_mirror_output_bundle)(struct ofproto *ofproto, void *aux); + + /* When the configuration option of forward_bpdu changes, this function + * will be invoked. */ + void (*forward_bpdu_changed)(struct ofproto *ofproto); }; extern const struct ofproto_class ofproto_dpif_class; diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index f40f99590..3df5526ca 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -322,6 +322,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type, ofproto->datapath_id = 0; ofproto_set_flow_eviction_threshold(ofproto, OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT); + ofproto->forward_bpdu = false; ofproto->fallback_dpid = pick_fallback_dpid(); ofproto->mfr_desc = xstrdup(DEFAULT_MFR_DESC); ofproto->hw_desc = xstrdup(DEFAULT_HW_DESC); @@ -421,6 +422,21 @@ ofproto_set_flow_eviction_threshold(struct ofproto *ofproto, unsigned threshold) } } +/* If forward_bpdu is true, the NORMAL action will forward frames with + * reserved (e.g. STP) destination Ethernet addresses. if forward_bpdu is false, + * the NORMAL action will drop these frames. */ +void +ofproto_set_forward_bpdu(struct ofproto *ofproto, bool forward_bpdu) +{ + bool old_val = ofproto->forward_bpdu; + ofproto->forward_bpdu = forward_bpdu; + if (old_val != ofproto->forward_bpdu) { + if (ofproto->ofproto_class->forward_bpdu_changed) { + ofproto->ofproto_class->forward_bpdu_changed(ofproto); + } + } +} + void ofproto_set_desc(struct ofproto *p, const char *mfr_desc, const char *hw_desc, diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 4975a8d3b..e0c99eac8 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -160,6 +160,7 @@ void ofproto_set_extra_in_band_remotes(struct ofproto *, const struct sockaddr_in *, size_t n); void ofproto_set_in_band_queue(struct ofproto *, int queue_id); void ofproto_set_flow_eviction_threshold(struct ofproto *, unsigned threshold); +void ofproto_set_forward_bpdu(struct ofproto *, bool forward_bpdu); void ofproto_set_desc(struct ofproto *, const char *mfr_desc, const char *hw_desc, const char *sw_desc, const char *serial_desc, diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index bd369eb7e..350288a85 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -150,6 +150,7 @@ static void bridge_refresh_ofp_port(struct bridge *); static void bridge_configure_datapath_id(struct bridge *); static void bridge_configure_flow_eviction_threshold(struct bridge *); static void bridge_configure_netflow(struct bridge *); +static void bridge_configure_forward_bpdu(struct bridge *); static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number); static void bridge_configure_remotes(struct bridge *, const struct sockaddr_in *managers, @@ -414,6 +415,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) bridge_configure_mirrors(br); bridge_configure_datapath_id(br); bridge_configure_flow_eviction_threshold(br); + bridge_configure_forward_bpdu(br); bridge_configure_remotes(br, managers, n_managers); bridge_configure_netflow(br); bridge_configure_sflow(br, &sflow_bridge_number); @@ -980,6 +982,20 @@ bridge_configure_flow_eviction_threshold(struct bridge *br) ofproto_set_flow_eviction_threshold(br->ofproto, threshold); } +/* Set forward BPDU option. */ +static void +bridge_configure_forward_bpdu(struct bridge *br) +{ + const char *forward_bpdu_str; + bool forward_bpdu = false; + + forward_bpdu_str = bridge_get_other_config(br->cfg, "forward-bpdu"); + if (forward_bpdu_str && !strcmp(forward_bpdu_str, "true")) { + forward_bpdu = true; + } + ofproto_set_forward_bpdu(br->ofproto, forward_bpdu); +} + static void bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN], struct iface **hw_addr_iface) diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index a8379526e..0d2c6ba05 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -461,6 +461,16 @@ <dd> Values below 100 will be rounded up to 100. </dd> + <dt><code>forward-bpdu</code></dt> + <dd> + Option to allow forwarding of BPDU frames when NORMAL + action if invoked. Frames with reserved Ethernet addresses + (e.g. STP BPDU) will be forwarded when this option is enabled. + If the Open vSwitch bridge is used to connect different + Ethernet networks, and if Open vSwtich node does not run STP, + then this option should be enabled. + Default is disabled, set to <code>true</code> to enable. + </dd> </dl> </column> </group> |