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 <lic...@chinatelecom.cn> --- 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 SRC 10.0.0.17]) + +dnl Add a route with disabled interface p2-route. +AT_CHECK([ip route add 10.0.1.18/32 dev p2-route]) +dnl Give the main thread a chance to act. +AT_CHECK([ovs-appctl revalidator/wait]) +dnl Check that OVS didn't refresh route table. +AT_CHECK([ovs-appctl ovs/route/show | grep 'p2-route' | sort], [0], [dnl +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 +]) + +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 95a65fcdc..217f5b3cf 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -71,6 +71,7 @@ #include "unixctl.h" #include "lib/vswitch-idl.h" #include "vlan-bitmap.h" +#include "route-table.h" VLOG_DEFINE_THIS_MODULE(bridge); @@ -888,6 +889,8 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) ofproto_set_threads( smap_get_int(&ovs_cfg->other_config, "n-handler-threads", 0), smap_get_int(&ovs_cfg->other_config, "n-revalidator-threads", 0)); + disable_notify_on_interfaces(smap_get(&ovs_cfg->other_config, + "route-notify-disabled-interfaces")); /* Destroy "struct bridge"s, "struct port"s, and "struct iface"s according * to 'ovs_cfg', with only very minimal configuration otherwise. diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 8a1b607d7..ee2ca05fd 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -869,6 +869,16 @@ The feature is considered experimental. </p> </column> + <column name="other_config" key="route-notify-disabled-interfaces"> + <p> + Ignore route changes of specified interfaces. One of the usage + scenarios is to prevent kubernets from triggering ovs route table + refresh on pod create/destroy. + </p> + <p> + The format is interface names joined by ','. i.e. "eth1,eth2" + </p> + </column> </group> <group title="Status"> <column name="next_cfg"> -- 2.39.3 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev