[ovs-dev] [PATCH] route-table: Filter route changes by interface.

2024-03-23 Thread Cheng Li
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.

2024-03-23 Thread Daniel Ding
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