[ovs-dev] [PATCH] route-table: Filter route changes by interface.
When ovs host is also a kubernets node, pod creation/deletion may trigger route changes. As a result, ovs run route_table_reset(). As ovs do not care the kubernetes pod routes, route_table_reset() is not neccessary. Signed-off-by: Cheng Li --- lib/route-table.c | 39 +++-- lib/route-table.h | 1 + tests/system-route.at | 51 +++ vswitchd/bridge.c | 3 +++ vswitchd/vswitch.xml | 10 + 5 files changed, 102 insertions(+), 2 deletions(-) diff --git a/lib/route-table.c b/lib/route-table.c index f1fe32714..ec8783923 100644 --- a/lib/route-table.c +++ b/lib/route-table.c @@ -33,6 +33,7 @@ #include "netlink-notifier.h" #include "netlink-socket.h" #include "openvswitch/ofpbuf.h" +#include "lib/sset.h" #include "ovs-router.h" #include "packets.h" #include "rtnetlink.h" @@ -82,6 +83,7 @@ static struct nln_notifier *route6_notifier = NULL; static struct nln_notifier *name_notifier = NULL; static bool route_table_valid = false; +static struct sset disabled_ifaces = SSET_INITIALIZER(&disabled_ifaces); static void route_table_reset(void); static void route_table_handle_msg(const struct route_table_msg *); @@ -92,6 +94,32 @@ static void route_map_clear(void); static void name_table_init(void); static void name_table_change(const struct rtnetlink_change *, void *); +void +disable_notify_on_interfaces(const char *ifaces) +{ +struct sset tmp_ifaces; + +if (ifaces) { +sset_from_delimited_string(&tmp_ifaces, ifaces, ", "); +} else { +sset_init(&tmp_ifaces); +} +if (! sset_equals(&disabled_ifaces, &tmp_ifaces)) { +const char *iface; +struct ds ds = DS_EMPTY_INITIALIZER; + +sset_swap(&disabled_ifaces, &tmp_ifaces); +SSET_FOR_EACH (iface, &disabled_ifaces) { +ds_put_format(&ds, " %s", iface); +} +VLOG_DBG_RL(&rl, "route notify disabled interfaces: [%s]", +ds_cstr(&ds)); +ds_destroy(&ds); +} +sset_destroy(&tmp_ifaces); + +} + uint64_t route_table_get_change_seq(void) { @@ -358,9 +386,16 @@ static void route_table_change(const struct route_table_msg *change OVS_UNUSED, void *aux OVS_UNUSED) { -if (!change || change->relevant) { -route_table_valid = false; +if (change) { +if (!change->relevant) { +return; +} +if (change->rd.ifname[0] != '\0' && +sset_contains(&disabled_ifaces, change->rd.ifname)) { +return; +} } +route_table_valid = false; } static void diff --git a/lib/route-table.h b/lib/route-table.h index 3a02d737a..716e5bae0 100644 --- a/lib/route-table.h +++ b/lib/route-table.h @@ -33,4 +33,5 @@ void route_table_wait(void); bool route_table_fallback_lookup(const struct in6_addr *ip6_dst, char name[], struct in6_addr *gw6); +void disable_notify_on_interfaces(const char *ifaces); #endif /* route-table.h */ diff --git a/tests/system-route.at b/tests/system-route.at index c0ecad6cf..039255df7 100644 --- a/tests/system-route.at +++ b/tests/system-route.at @@ -128,3 +128,54 @@ OVS_WAIT_UNTIL([test $(ovs-appctl ovs/route/show | grep -c 'p1-route') -eq 0 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP + + +dnl Checks that disabled interface doesn't trigger route table refresh. +AT_SETUP([ovs-route - filter by interface]) +AT_KEYWORDS([route]) +OVS_TRAFFIC_VSWITCHD_START() + +dnl Create tap port. +on_exit 'ip link del p1-route; ip link del p2-route' +AT_CHECK([ip tuntap add name p1-route mode tap]) +AT_CHECK([ip tuntap add name p2-route mode tap]) +AT_CHECK([ip link set p1-route up]) +AT_CHECK([ip link set p2-route up]) + +dnl Add ip address. +AT_CHECK([ip addr add 10.0.0.17/24 dev p1-route], [0], [stdout]) +AT_CHECK([ip addr add 10.0.1.17/24 dev p2-route], [0], [stdout]) + +dnl Check that OVS catches route updates. +OVS_WAIT_UNTIL_EQUAL([ovs-appctl ovs/route/show | grep -P 'p(1|2)-route' | sort], [dnl +Cached: 10.0.0.0/24 dev p1-route SRC 10.0.0.17 +Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local +Cached: 10.0.1.0/24 dev p2-route SRC 10.0.1.17 +Cached: 10.0.1.17/32 dev p2-route SRC 10.0.1.17 local]) + +dnl Set disabled interface +AT_CHECK([ovs-appctl vlog/set 'route_table,dbg']) +get_log_next_line_num +AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:route-notify-disabled-interfaces="p2-route"]) +dnl expected log line: "route_table|DBG|route notify disabled interfaces: [ p2-route]" +OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep -P "notify disabled interfaces: . p2-route"]) + +dnl Add a route with interface p1-route. +AT_CHECK([ip route add 10.0.0.18/32 dev p1-route]) +OVS_WAIT_UNTIL_EQUAL([ovs-appctl ovs/route/show | grep 'p1-route' | sort], [dnl +Cached: 10.0.0.0/24 dev p1-route SRC 10.0.0.17 +Cached: 10.0.0.17/32 dev p1-route SRC 10.0.0.17 local +Cached: 10.0.0.18/32 dev p1-route SR
[ovs-dev] [PATCH] ovs-tcpdump: Support vlan option.
When I try filter geneve protocol with a vlan, the warning message occurs that tell me the kernel cann't support this combination. $ ovs-tcpdump -i eth2 -nne vlan 10 and geneve Warning: Kernel filter failed: Invalid argument So I fix it by the following: 1. the mirror-to interface was added with a vlan tag, which let datapath to pop its tag. 2. the traffic will be mirrored with mirror's select_vlan, and that don't care about will not be received on the mirror-to interface. Signed-off-by: Daniel Ding --- utilities/ovs-tcpdump.in | 37 + 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/utilities/ovs-tcpdump.in b/utilities/ovs-tcpdump.in index eada803bb..b2b69d3c4 100755 --- a/utilities/ovs-tcpdump.in +++ b/utilities/ovs-tcpdump.in @@ -142,6 +142,8 @@ The following options are available: --mirror-toThe name for the mirror port to use (optional) Default 'miINTERFACE' --span If specified, mirror all ports (optional) + --vlan If specified, mirror a vlan traffic and pop + its tag (optional) """ % {'prog': sys.argv[0]}) sys.exit(0) @@ -319,7 +321,7 @@ class OVSDB(object): (mirror_name, txn.get_error())) self._txn = None -def make_port(self, port_name, bridge_name): +def make_port(self, port_name, bridge_name, vlan=None): iface_row = self.make_interface(port_name, False) txn = self._txn @@ -330,6 +332,12 @@ class OVSDB(object): port = txn.insert(self.get_table('Port')) port.name = port_name +if vlan is not None: +port.verify('tag') +tag = getattr(port, 'tag', []) +tag.append(vlan) +port.tag = tag + br.verify('ports') ports = getattr(br, 'ports', []) ports.append(port) @@ -354,7 +362,7 @@ class OVSDB(object): return result def bridge_mirror(self, intf_name, mirror_intf_name, br_name, - mirror_select_all=False): + mirror_select_all=False, mirrored_vlan=None): txn = self._start_txn() mirror = txn.insert(self.get_table('Mirror')) @@ -374,6 +382,12 @@ class OVSDB(object): src_port.append(mirrored_port) mirror.select_src_port = src_port +if mirrored_vlan: +mirror.verify('select_vlan') +select_vlan = getattr(mirror, 'select_vlan', []) +select_vlan.append(mirrored_vlan) +mirror.select_vlan = select_vlan + output_port = self._find_row_by_name('Port', mirror_intf_name) mirror.verify('output_port') @@ -440,6 +454,7 @@ def main(): db_sock = 'unix:%s' % os.path.join(rundir, "db.sock") interface = None tcpdargs = [] +vlan = None skip_next = False mirror_interface = None @@ -474,12 +489,25 @@ def main(): elif cur in ['--span']: mirror_select_all = True continue +elif cur in ['--vlan']: +vlan = nxt +skip_next = True +continue tcpdargs.append(cur) if interface is None: print("Error: must at least specify an interface with '-i' option") sys.exit(1) +if vlan: +try: +vlan = int(vlan) +if vlan < 0 or vlan > 4095: +raise ValueError("out of range") +except ValueError: +print("Error: vlan muse be within <0-4095>") +sys.exit(1) + if not py_which(dump_cmd): print("Error: unable to execute '%s' (check PATH)" % dump_cmd) sys.exit(1) @@ -523,10 +551,11 @@ def main(): teardown(db_sock, interface, mirror_interface, tap_created) try: -ovsdb.make_port(mirror_interface, ovsdb.port_bridge(interface)) +ovsdb.make_port(mirror_interface, +ovsdb.port_bridge(interface), vlan) ovsdb.bridge_mirror(interface, mirror_interface, ovsdb.port_bridge(interface), -mirror_select_all) +mirror_select_all, vlan) except OVSDBException as oe: print("ERROR: Unable to properly setup the mirror: %s." % str(oe)) sys.exit(1) -- 2.43.0 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev