From bbbca389c002f740dffd0d8c24f13e562efaa876 Mon Sep 17 00:00:00 2001 From: Padmanabhan Krishnan Date: Thu, 24 Apr 2014 13:18:18 -0700 Subject: [PATCH] ofproto-dpif-xlate: Identify STP BPDUs more specifically. Apart from STP, EVB extension of LLDP as well as IEEE 802.1QBG use the Nearest Customer Bridge (NCB) DMAC which has a value of 0180.c200.0000. STP can be distinguished by Ethertype from these protocols. Signed-off-by: Padmanabhan Krishnan [blp@nicira.com rewrote the details of the patch] Signed-off-by: Ben Pfaff Tested-by: Padmanabhan Krishnan --- AUTHORS | 2 +- lib/flow.h | 6 ++++++ ofproto/ofproto-dpif-xlate.c | 7 ++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4881c25df..16255d4f4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -86,6 +86,7 @@ Murphy McCauley murphy.mccauley@gmail.com Natasha Gude natasha@nicira.com Neil McKee neil.mckee@inmon.com Neil Zhu zhuj@centecnetworks.com +Padmanabhan Krishnan kprad1@yahoo.com Paraneetharan Chandrasekaran paraneetharanc@gmail.com Paul Fazzone pfazzone@nicira.com Paul Ingram paul@nicira.com @@ -225,7 +226,6 @@ Min Chen ustcer.tonychan@gmail.com Mikael Doverhag mdoverhag@nicira.com Nagi Reddy Jonnala njonnala@Brocade.com Niklas Andersson nandersson@nicira.com -Padmanabhan Krishnan kprad1@yahoo.com Pankaj Thakkar thakkar@nicira.com Pasi Kärkkäinen pasik@iki.fi Paulo Cravero pcravero@as2594.net diff --git a/lib/flow.h b/lib/flow.h index 413ecb5a9..e63e4e2b2 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -617,4 +617,10 @@ static inline bool is_icmpv6(const struct flow *flow) && flow->nw_proto == IPPROTO_ICMPV6); } +static inline bool is_stp(const struct flow *flow) +{ + return (eth_addr_equals(flow->dl_dst, eth_addr_stp) + && flow->dl_type == htons(FLOW_DL_TYPE_NONE)); +} + #endif /* flow.h */ diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 6a56a1556..4a9ba5203 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -770,8 +770,9 @@ xport_stp_listen_state(const struct xport *xport) static bool stp_should_process_flow(const struct flow *flow, struct flow_wildcards *wc) { + /* is_stp() also checks dl_type, but dl_type is always set in 'wc'. */ memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst); - return eth_addr_equals(flow->dl_dst, eth_addr_stp); + return is_stp(flow); } static void @@ -1820,7 +1821,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, xlate_report(ctx, "OFPPC_NO_FWD set, skipping output"); return; } else if (check_stp) { - if (eth_addr_equals(ctx->base_flow.dl_dst, eth_addr_stp)) { + if (is_stp(&ctx->base_flow)) { if (!xport_stp_listen_state(xport)) { xlate_report(ctx, "STP not in listening state, " "skipping bpdu output"); @@ -2724,7 +2725,7 @@ xlate_sample_action(struct xlate_ctx *ctx, static bool may_receive(const struct xport *xport, struct xlate_ctx *ctx) { - if (xport->config & (eth_addr_equals(ctx->xin->flow.dl_dst, eth_addr_stp) + if (xport->config & (is_stp(&ctx->xin->flow) ? OFPUTIL_PC_NO_RECV_STP : OFPUTIL_PC_NO_RECV)) { return false; -- 2.43.0