STT uses TCP port so we need to filter traffic on basis of TCP port numbers.
Signed-off-by: Pravin B Shelar <pshe...@ovn.org> --- lib/tnl-ports.c | 82 +++++++++++++++++++++++++++++++++++++------------------- lib/tnl-ports.h | 4 +-- ofproto/tunnel.c | 8 ++++-- 3 files changed, 62 insertions(+), 32 deletions(-) diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c index f399d04..e8d43f0 100644 --- a/lib/tnl-ports.c +++ b/lib/tnl-ports.c @@ -51,7 +51,8 @@ static struct ovs_list addr_list; struct tnl_port { odp_port_t port; - ovs_be16 udp_port; + ovs_be16 tp_port; + uint8_t nw_proto; char dev_name[IFNAMSIZ]; struct ovs_list node; }; @@ -82,7 +83,7 @@ tnl_port_free(struct tnl_port_in *p) static void tnl_port_init_flow(struct flow *flow, struct eth_addr mac, - struct in6_addr *addr, ovs_be16 udp_port) + struct in6_addr *addr, uint8_t nw_proto, ovs_be16 tp_port) { memset(flow, 0, sizeof *flow); @@ -95,24 +96,20 @@ tnl_port_init_flow(struct flow *flow, struct eth_addr mac, flow->ipv6_dst = *addr; } - if (udp_port) { - flow->nw_proto = IPPROTO_UDP; - } else { - flow->nw_proto = IPPROTO_GRE; - } - flow->tp_dst = udp_port; + flow->nw_proto = nw_proto; + flow->tp_dst = tp_port; } static void map_insert(odp_port_t port, struct eth_addr mac, struct in6_addr *addr, - ovs_be16 udp_port, const char dev_name[]) + uint8_t nw_proto, ovs_be16 tp_port, const char dev_name[]) { const struct cls_rule *cr; struct tnl_port_in *p; struct match match; memset(&match, 0, sizeof match); - tnl_port_init_flow(&match.flow, mac, addr, udp_port); + tnl_port_init_flow(&match.flow, mac, addr, nw_proto, tp_port); do { cr = classifier_lookup(&cls, CLS_MAX_VERSION, &match.flow, NULL); @@ -129,9 +126,9 @@ map_insert(odp_port_t port, struct eth_addr mac, struct in6_addr *addr, /* XXX: No fragments support. */ match.wc.masks.nw_frag = FLOW_NW_FRAG_MASK; - /* 'udp_port' is zero for non-UDP tunnels (e.g. GRE). In this case it + /* 'tp_port' is zero for GRE tunnels. In this case it * doesn't make sense to match on UDP port numbers. */ - if (udp_port) { + if (tp_port) { match.wc.masks.tp_dst = OVS_BE16_MAX; } if (IN6_IS_ADDR_V4MAPPED(addr)) { @@ -152,40 +149,65 @@ map_insert(odp_port_t port, struct eth_addr mac, struct in6_addr *addr, static void map_insert_ipdev__(struct ip_device *ip_dev, char dev_name[], - odp_port_t port, ovs_be16 udp_port) + odp_port_t port, uint8_t nw_proto, ovs_be16 tp_port) { if (ip_dev->n_addr) { int i; for (i = 0; i < ip_dev->n_addr; i++) { map_insert(port, ip_dev->mac, &ip_dev->addr[i], - udp_port, dev_name); + nw_proto, tp_port, dev_name); } } } +static uint8_t +tnl_type_to_nw_proto(const char type[]) +{ + if (!strcmp(type, "geneve")) { + return IPPROTO_UDP; + } + if (!strcmp(type, "stt")) { + return IPPROTO_TCP; + } + if (!strcmp(type, "gre")) { + return IPPROTO_GRE; + } + if (!strcmp(type, "vxlan")) { + return IPPROTO_UDP; + } + return 0; +} + void -tnl_port_map_insert(odp_port_t port, - ovs_be16 udp_port, const char dev_name[]) +tnl_port_map_insert(odp_port_t port, ovs_be16 tp_port, + const char dev_name[], const char type[]) { struct tnl_port *p; struct ip_device *ip_dev; + uint8_t nw_proto; + + nw_proto = tnl_type_to_nw_proto(type); + if (!nw_proto) { + return; + } ovs_mutex_lock(&mutex); LIST_FOR_EACH(p, node, &port_list) { - if (udp_port == p->udp_port) { + if (tp_port == p->tp_port && p->nw_proto == nw_proto) { goto out; } } p = xzalloc(sizeof *p); p->port = port; - p->udp_port = udp_port; + p->tp_port = tp_port; + p->nw_proto = nw_proto; ovs_strlcpy(p->dev_name, dev_name, sizeof p->dev_name); ovs_list_insert(&port_list, &p->node); LIST_FOR_EACH(ip_dev, node, &addr_list) { - map_insert_ipdev__(ip_dev, p->dev_name, p->port, p->udp_port); + map_insert_ipdev__(ip_dev, p->dev_name, p->port, p->nw_proto, p->tp_port); } out: @@ -205,39 +227,43 @@ tnl_port_unref(const struct cls_rule *cr) } static void -map_delete(struct eth_addr mac, struct in6_addr *addr, ovs_be16 udp_port) +map_delete(struct eth_addr mac, struct in6_addr *addr, + ovs_be16 tp_port, uint8_t nw_proto) { const struct cls_rule *cr; struct flow flow; - tnl_port_init_flow(&flow, mac, addr, udp_port); + tnl_port_init_flow(&flow, mac, addr, nw_proto, tp_port); cr = classifier_lookup(&cls, CLS_MAX_VERSION, &flow, NULL); tnl_port_unref(cr); } static void -ipdev_map_delete(struct ip_device *ip_dev, ovs_be16 udp_port) +ipdev_map_delete(struct ip_device *ip_dev, ovs_be16 tp_port, uint8_t nw_proto) { if (ip_dev->n_addr) { int i; for (i = 0; i < ip_dev->n_addr; i++) { - map_delete(ip_dev->mac, &ip_dev->addr[i], udp_port); + map_delete(ip_dev->mac, &ip_dev->addr[i], tp_port, nw_proto); } } } void -tnl_port_map_delete(ovs_be16 udp_port) +tnl_port_map_delete(ovs_be16 tp_port, const char type[]) { struct tnl_port *p, *next; struct ip_device *ip_dev; bool found = false; + uint8_t nw_proto; + + nw_proto = tnl_type_to_nw_proto(type); ovs_mutex_lock(&mutex); LIST_FOR_EACH_SAFE(p, next, node, &port_list) { - if (p->udp_port == udp_port) { + if (p->tp_port == tp_port && p->nw_proto == nw_proto) { ovs_list_remove(&p->node); found = true; break; @@ -248,7 +274,7 @@ tnl_port_map_delete(ovs_be16 udp_port) goto out; } LIST_FOR_EACH(ip_dev, node, &addr_list) { - ipdev_map_delete(ip_dev, p->udp_port); + ipdev_map_delete(ip_dev, p->tp_port, p->nw_proto); } free(p); @@ -343,7 +369,7 @@ map_insert_ipdev(struct ip_device *ip_dev) struct tnl_port *p; LIST_FOR_EACH(p, node, &port_list) { - map_insert_ipdev__(ip_dev, p->dev_name, p->port, p->udp_port); + map_insert_ipdev__(ip_dev, p->dev_name, p->port, p->nw_proto, p->tp_port); } } @@ -409,7 +435,7 @@ delete_ipdev(struct ip_device *ip_dev) struct tnl_port *p; LIST_FOR_EACH(p, node, &port_list) { - ipdev_map_delete(ip_dev, p->udp_port); + ipdev_map_delete(ip_dev, p->tp_port, p->nw_proto); } ovs_list_remove(&ip_dev->node); diff --git a/lib/tnl-ports.h b/lib/tnl-ports.h index 4195e6a..58b048a 100644 --- a/lib/tnl-ports.h +++ b/lib/tnl-ports.h @@ -27,9 +27,9 @@ odp_port_t tnl_port_map_lookup(struct flow *flow, struct flow_wildcards *wc); void tnl_port_map_insert(odp_port_t port, ovs_be16 udp_port, - const char dev_name[]); + const char dev_name[], const char type[]); -void tnl_port_map_delete(ovs_be16 udp_port); +void tnl_port_map_delete(ovs_be16 udp_port, const char type[]); void tnl_port_map_insert_ipdev(const char dev[]); void tnl_port_map_delete_ipdev(const char dev[]); void tnl_port_map_run(void); diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index e65a2e4..cc04ca5 100644 --- a/ofproto/tunnel.c +++ b/ofproto/tunnel.c @@ -194,7 +194,11 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev, tnl_port_mod_log(tnl_port, "adding"); if (native_tnl) { - tnl_port_map_insert(odp_port, cfg->dst_port, name); + const char *type; + + type = netdev_get_type(netdev); + tnl_port_map_insert(odp_port, cfg->dst_port, name, type); + } return true; } @@ -261,7 +265,7 @@ tnl_port_del__(const struct ofport_dpif *ofport) OVS_REQ_WRLOCK(rwlock) netdev_get_tunnel_config(tnl_port->netdev); struct hmap **map; - tnl_port_map_delete(cfg->dst_port); + tnl_port_map_delete(cfg->dst_port, netdev_get_type(tnl_port->netdev)); tnl_port_mod_log(tnl_port, "removing"); map = tnl_match_map(&tnl_port->match); hmap_remove(*map, &tnl_port->match_node); -- 2.5.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev