From 07509878e37b7f6ce75e4168e450cee3b36f24e9 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 26 Sep 2019 18:49:59 +0200 Subject: zebra: importation of bgp evpn rt5 from vni with other netns With vrf-lite mechanisms, it is possible to create layer 3 vnis by creating a bridge interface in default vr, by creating a vxlan interface that is attached to that bridge interface, then by moving the vxlan interface to the wished vrf. With vrf-netns mechanism, it is slightly different since bridged interfaces can not be separated in different network namespaces. To make it work, the setup consists in : - creating a vxlan interface on default vrf. - move the vxlan interface to the wished vrf ( with an other netns) - create a bridge interface in the wished vrf - attach the vxlan interface to that bridged interface from that point, if BGP is enabled to advertise vnis in default vrf, then vxlan interfaces are discovered appropriately in other vrfs, provided that the link interface still resides in the vrf where l2vpn is advertised. to import ipv4 entries from a separate vrf, into the l2vpn, the configuration of vni in the dedicated vrf + the advertisement of ipv4 entries in bgp vrf will import the entries in the bgp l2vpn. the modification consists in parsing the vxlan interfaces in all network namespaces, where the link resides in the same network namespace as the bgp core instance where bgp l2vpn is enabled. Signed-off-by: Philippe Guibert --- lib/netns_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/netns_linux.c') diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 98f359401e..09a42b850b 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -51,7 +51,7 @@ static struct ns *ns_lookup_name_internal(const char *name); RB_GENERATE(ns_head, ns, entry, ns_compare) -static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree); +struct ns_head ns_tree = RB_INITIALIZER(&ns_tree); static struct ns *default_ns; static int ns_current_ns_fd; -- cgit v1.2.3 From 2d4e4d39b776c0a389712be6cbb0b28cf7aa33ad Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 2 Oct 2019 12:14:13 +0200 Subject: zebra, lib: add an internal API to get relative default nsid in other ns as remind, the netns identifiers are local to a namespace. that is to say that for instance, a vrf will have a netns id value in one netns, and have an other netns id value in one other netns. There is a need for zebra daemon to collect some cross information, like the LINK_NETNSID information from interfaces having link layer in an other network namespace. For that, it is needed to have a global overview instead of a relative overview per namespace. The first brick of this change is an API that sticks to netlink API, that uses NETNSA_TARGET_NSID. from a given vrf vrfX, and a new vrf created vrfY, the API returns the value of nsID from vrfX, inside the new vrf vrfY. The brick also gets the ns id value of default namespace in each other namespace. An additional value in ns.h is offered, that permits to retrieve the default namespace context. Signed-off-by: Philippe Guibert --- include/linux/net_namespace.h | 1 + lib/netns_linux.c | 6 +++ lib/ns.h | 1 + zebra/zebra_netns_id.c | 90 +++++++++++++++++++++++++++++++++++++++++++ zebra/zebra_netns_id.h | 2 + zebra/zebra_netns_notify.c | 12 +++++- 6 files changed, 111 insertions(+), 1 deletion(-) (limited to 'lib/netns_linux.c') diff --git a/include/linux/net_namespace.h b/include/linux/net_namespace.h index 0187c74d88..0ed9dd61d3 100644 --- a/include/linux/net_namespace.h +++ b/include/linux/net_namespace.h @@ -16,6 +16,7 @@ enum { NETNSA_NSID, NETNSA_PID, NETNSA_FD, + NETNSA_TARGET_NSID, __NETNSA_MAX, }; diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 09a42b850b..bb66e8938f 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -590,3 +590,9 @@ ns_id_t ns_get_default_id(void) return default_ns->ns_id; return NS_DEFAULT_INTERNAL; } + +struct ns *ns_get_default(void) +{ + return default_ns; +} + diff --git a/lib/ns.h b/lib/ns.h index 1963b8a359..c594cbfac9 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -177,6 +177,7 @@ extern struct ns *ns_lookup_name(const char *name); extern int ns_enable(struct ns *ns, void (*func)(ns_id_t, void *)); extern struct ns *ns_get_created(struct ns *ns, char *name, ns_id_t ns_id); extern void ns_disable(struct ns *ns); +extern struct ns *ns_get_default(void); #ifdef __cplusplus } diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index 8de4daf439..61d2ebe184 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -315,11 +315,101 @@ ns_id_t zebra_ns_id_get(const char *netnspath) return return_nsid; } +/* if nsid is not default one, get relative default ns for the new ns + * for instance, if default ns is 0 and a new ns "vrf1" id is 1, + * in ns "vrf1", the default ns is not known. using GETNSID with + * two parameters: NETNS_NSID, and NETNS_TARGET_NSID will help + * in identifying that value + */ +ns_id_t zebra_ns_id_get_relative_value(ns_id_t ns_read, ns_id_t target_nsid) +{ + struct sockaddr_nl snl; + int sock, ret; + unsigned int seq; + ns_id_t return_nsid = NS_UNKNOWN; + char buf[NETLINK_SOCKET_BUFFER_SIZE]; + struct nlmsghdr *nlh; + struct rtgenmsg *rt; + int len; + + if (ns_read == NS_UNKNOWN || target_nsid == NS_UNKNOWN) + return return_nsid; + + /* netlink socket */ + sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (sock < 0) { + flog_err_sys(EC_LIB_SOCKET, "netlink( %u) socket() error: %s", + sock, safe_strerror(errno)); + return NS_UNKNOWN; + } + memset(&snl, 0, sizeof(snl)); + snl.nl_family = AF_NETLINK; + snl.nl_groups = RTNLGRP_NSID; + snl.nl_pid = 0; /* AUTO PID */ + ret = bind(sock, (struct sockaddr *)&snl, sizeof(snl)); + if (ret < 0) { + flog_err_sys(EC_LIB_SOCKET, + "netlink( %u) socket() bind error: %s", sock, + safe_strerror(errno)); + close(sock); + return NS_UNKNOWN; + } + + /* message to send to netlink : GETNSID */ + memset(buf, 0, NETLINK_SOCKET_BUFFER_SIZE); + nlh = initiate_nlh(buf, &seq, RTM_GETNSID); + rt = (struct rtgenmsg *)(buf + nlh->nlmsg_len); + nlh->nlmsg_len += NETLINK_ALIGN(sizeof(struct rtgenmsg)); + rt->rtgen_family = AF_UNSPEC; + + addattr32(nlh, NETLINK_SOCKET_BUFFER_SIZE, NETNSA_NSID, ns_read); + addattr32(nlh, NETLINK_SOCKET_BUFFER_SIZE, NETNSA_TARGET_NSID, target_nsid); + + ret = send_receive(sock, nlh, seq, buf); + if (ret < 0) { + close(sock); + return NS_UNKNOWN; + } + nlh = (struct nlmsghdr *)buf; + len = ret; + ret = 0; + do { + if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) { + return_nsid = extract_nsid(nlh, buf); + if (return_nsid != NS_UNKNOWN) + break; + } else if (nlh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = + (struct nlmsgerr + *)((char *)nlh + + NETLINK_ALIGN(sizeof( + struct + nlmsghdr))); + if (err->error < 0) + errno = -err->error; + else + errno = err->error; + break; + } + len = len - NETLINK_ALIGN(nlh->nlmsg_len); + nlh = (struct nlmsghdr *)((char *)nlh + + NETLINK_ALIGN( + nlh->nlmsg_len)); + } while (len != 0 && ret == 0); + + return return_nsid; +} + #else ns_id_t zebra_ns_id_get(const char *netnspath) { return zebra_ns_id_get_fallback(netnspath); } + +ns_id_t zebra_ns_id_get_relative_value(ns_id_t ns_read, ns_id_t target_nsid) +{ + return NS_UNKNOWN; +} #endif /* ! defined(HAVE_NETLINK) */ #ifdef HAVE_NETNS diff --git a/zebra/zebra_netns_id.h b/zebra/zebra_netns_id.h index 7a5f6851f4..215d627b7b 100644 --- a/zebra/zebra_netns_id.h +++ b/zebra/zebra_netns_id.h @@ -26,6 +26,8 @@ extern "C" { extern ns_id_t zebra_ns_id_get(const char *netnspath); extern ns_id_t zebra_ns_id_get_default(void); +extern ns_id_t zebra_ns_id_get_relative_value(ns_id_t ns_read, + ns_id_t target_nsid); #ifdef __cplusplus } diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index ec7681bf23..db620cf220 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -72,7 +72,8 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name) char *netnspath = ns_netns_pathname(NULL, name); struct vrf *vrf; int ret; - ns_id_t ns_id, ns_id_external; + ns_id_t ns_id, ns_id_external, ns_id_relative = NS_UNKNOWN; + struct ns *default_ns; if (netnspath == NULL) return; @@ -82,6 +83,15 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name) } if (ns_id == NS_UNKNOWN) return; + default_ns = ns_get_default(); + if (default_ns && default_ns->internal_ns_id != ns_id) { + frr_with_privs(&zserv_privs) { + ns_id_relative = + zebra_ns_id_get_relative_value( + default_ns->internal_ns_id, + ns_id); + } + } ns_id_external = ns_map_nsid_with_external(ns_id, true); /* if VRF with NS ID already present */ vrf = vrf_lookup_by_id((vrf_id_t)ns_id_external); -- cgit v1.2.3 From b1cc23b2cdaf70b279dfe53aa8ded6e2e6d3b1fd Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 2 Oct 2019 13:37:11 +0200 Subject: zebra, lib: new API to get absolute netns val from relative netns val when receiving a netlink API for an interface in a namespace, this interface may come with LINK_NSID value, which means that the interface has its link in an other namespace. Unfortunately, the link_nsid value is self to that namespace, and there is a need to know what is its associated nsid value from the default namespace point of view. The information collected previously on each namespace, can then be compared with that value to check if the link belongs to the default namespace or not. Signed-off-by: Philippe Guibert --- lib/netns_linux.c | 20 ++++++++++++++++++++ lib/ns.h | 1 + zebra/if_netlink.c | 9 ++++++--- 3 files changed, 27 insertions(+), 3 deletions(-) (limited to 'lib/netns_linux.c') diff --git a/lib/netns_linux.c b/lib/netns_linux.c index bb66e8938f..0109b3db6a 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -584,6 +584,26 @@ int ns_socket(int domain, int type, int protocol, ns_id_t ns_id) return ret; } +/* if relative link_nsid matches default netns, + * then return default absolute netns value + * otherwise, return NS_UNKNOWN + */ +ns_id_t ns_id_get_absolute(ns_id_t ns_id_reference, ns_id_t link_nsid) +{ + struct ns *ns; + + ns = ns_lookup(ns_id_reference); + if (!ns) + return NS_UNKNOWN; + + if (ns->relative_default_ns != link_nsid) + return NS_UNKNOWN; + + ns = ns_get_default(); + assert(ns); + return ns->ns_id; +} + ns_id_t ns_get_default_id(void) { if (default_ns) diff --git a/lib/ns.h b/lib/ns.h index 188161e11a..0dfd977429 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -181,6 +181,7 @@ extern struct ns *ns_lookup_name(const char *name); */ extern int ns_enable(struct ns *ns, void (*func)(ns_id_t, void *)); extern struct ns *ns_get_created(struct ns *ns, char *name, ns_id_t ns_id); +extern ns_id_t ns_id_get_absolute(ns_id_t ns_id_reference, ns_id_t link_nsid); extern void ns_disable(struct ns *ns); extern struct ns *ns_get_default(void); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 5cd3e69299..c3eab60148 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -798,8 +798,10 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (tb[IFLA_LINK]) link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]); - if (tb[IFLA_LINK_NETNSID]) + if (tb[IFLA_LINK_NETNSID]) { link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]); + link_nsid = ns_id_get_absolute(ns_id, link_nsid); + } /* Add interface. * We add by index first because in some cases such as the master @@ -1349,9 +1351,10 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (tb[IFLA_LINK]) link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]); - if (tb[IFLA_LINK_NETNSID]) + if (tb[IFLA_LINK_NETNSID]) { link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]); - + link_nsid = ns_id_get_absolute(ns_id, link_nsid); + } if (tb[IFLA_IFALIAS]) { desc = (char *)RTA_DATA(tb[IFLA_IFALIAS]); } -- cgit v1.2.3 From 2961d0601c7d168eed5bbe8e95f80a642f9cb4b5 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 20 Dec 2019 17:51:37 +0100 Subject: lib, zebra: reuse and adapt ns_list walk functionality the walk routine is used by vxlan service to identify some contexts in each specific network namespace, when vrf netns backend is used. that walk mechanism is extended with some additional paramters to the walk routine. Signed-off-by: Philippe Guibert --- lib/netns_linux.c | 16 +++++++++---- lib/netns_other.c | 2 +- lib/ns.h | 11 ++++++--- zebra/main.c | 4 ++-- zebra/zebra_evpn.c | 36 +++++++++++++++------------- zebra/zebra_ns.c | 35 +++++++-------------------- zebra/zebra_ns.h | 17 +++++-------- zebra/zebra_vxlan.c | 69 +++++++++++++++++++++++++++++------------------------ 8 files changed, 95 insertions(+), 95 deletions(-) (limited to 'lib/netns_linux.c') diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 0109b3db6a..e8d549b4e0 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -51,7 +51,7 @@ static struct ns *ns_lookup_name_internal(const char *name); RB_GENERATE(ns_head, ns, entry, ns_compare) -struct ns_head ns_tree = RB_INITIALIZER(&ns_tree); +static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree); static struct ns *default_ns; static int ns_current_ns_fd; @@ -379,12 +379,20 @@ struct ns *ns_lookup(ns_id_t ns_id) return ns_lookup_internal(ns_id); } -void ns_walk_func(int (*func)(struct ns *)) +void ns_walk_func(int (*func)(struct ns *, + void *param_in, + void **param_out), + void *param_in, + void **param_out) { struct ns *ns = NULL; + int ret; - RB_FOREACH (ns, ns_head, &ns_tree) - func(ns); + RB_FOREACH (ns, ns_head, &ns_tree) { + ret = func(ns, param_in, param_out); + if (ret == NS_WALK_STOP) + return; + } } const char *ns_get_name(struct ns *ns) diff --git a/lib/netns_other.c b/lib/netns_other.c index b0aae4f8df..740d2b621e 100644 --- a/lib/netns_other.c +++ b/lib/netns_other.c @@ -34,7 +34,7 @@ static inline int ns_compare(const struct ns *ns, const struct ns *ns2); RB_GENERATE(ns_head, ns, entry, ns_compare) -struct ns_head ns_tree = RB_INITIALIZER(&ns_tree); +static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree); static inline int ns_compare(const struct ns *a, const struct ns *b) { diff --git a/lib/ns.h b/lib/ns.h index 0dfd977429..286ff5b295 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -76,8 +76,6 @@ struct ns { RB_HEAD(ns_head, ns); RB_PROTOTYPE(ns_head, ns, entry, ns_compare) -extern struct ns_head ns_tree; - /* * API for managing NETNS. eg from zebra daemon * one want to manage the list of NETNS, etc... @@ -127,7 +125,14 @@ int ns_socket(int domain, int type, int protocol, ns_id_t ns_id); extern char *ns_netns_pathname(struct vty *vty, const char *name); /* Parse and execute a function on all the NETNS */ -extern void ns_walk_func(int (*func)(struct ns *)); +#define NS_WALK_CONTINUE 0 +#define NS_WALK_STOP 1 + +extern void ns_walk_func(int (*func)(struct ns *, + void *, + void **), + void *param_in, + void **param_out); /* API to get the NETNS name, from the ns pointer */ extern const char *ns_get_name(struct ns *ns); diff --git a/zebra/main.c b/zebra/main.c index 64746f7166..2b97e915fb 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -187,7 +187,7 @@ static void sigint(void) vrf_terminate(); rtadv_terminate(); - ns_walk_func(zebra_ns_early_shutdown); + ns_walk_func(zebra_ns_early_shutdown, NULL, NULL); zebra_ns_notify_close(); access_list_reset(); @@ -218,7 +218,7 @@ int zebra_finalize(struct thread *dummy) zlog_info("Zebra final shutdown"); /* Final shutdown of ns resources */ - ns_walk_func(zebra_ns_final_shutdown); + ns_walk_func(zebra_ns_final_shutdown, NULL, NULL); /* Stop dplane thread and finish any cleanup */ zebra_dplane_shutdown(); diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 542f36156e..0f5e77ac65 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -622,10 +622,11 @@ void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket, return; } -static int zebra_evpn_map_vlan_zns(struct zebra_ns *zns, - void *_in_param, - void **_p_zevpn) +static int zebra_evpn_map_vlan_ns(struct ns *ns, + void *_in_param, + void **_p_zevpn) { + struct zebra_ns *zns = ns->info; struct route_node *rn; struct interface *br_if; zebra_evpn_t **p_zevpn = (zebra_evpn_t **)_p_zevpn; @@ -638,7 +639,7 @@ static int zebra_evpn_map_vlan_zns(struct zebra_ns *zns, int found = 0; if (!in_param) - return ZNS_WALK_STOP; + return NS_WALK_STOP; br_if = in_param->br_if; zif = in_param->zif; assert(zif); @@ -667,12 +668,12 @@ static int zebra_evpn_map_vlan_zns(struct zebra_ns *zns, } } if (!found) - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; zevpn = zebra_evpn_lookup(vxl->vni); if (p_zevpn) *p_zevpn = zevpn; - return ZNS_WALK_STOP; + return NS_WALK_STOP; } /* @@ -698,16 +699,17 @@ zebra_evpn_t *zebra_evpn_map_vlan(struct interface *ifp, in_param.zif = zif; p_zevpn = &zevpn; - zebra_ns_list_walk(zebra_evpn_map_vlan_zns, - (void *)&in_param, - (void **)p_zevpn); + ns_walk_func(zebra_evpn_map_vlan_ns, + (void *)&in_param, + (void **)p_zevpn); return zevpn; } -static int zebra_evpn_from_svi_zns(struct zebra_ns *zns, - void *_in_param, - void **_p_zevpn) +static int zebra_evpn_from_svi_ns(struct ns *ns, + void *_in_param, + void **_p_zevpn) { + struct zebra_ns *zns = ns->info; struct route_node *rn; struct interface *br_if; zebra_evpn_t **p_zevpn = (zebra_evpn_t **)_p_zevpn; @@ -720,7 +722,7 @@ static int zebra_evpn_from_svi_zns(struct zebra_ns *zns, int found = 0; if (!in_param) - return ZNS_WALK_STOP; + return NS_WALK_STOP; br_if = in_param->br_if; zif = in_param->zif; assert(zif); @@ -748,12 +750,12 @@ static int zebra_evpn_from_svi_zns(struct zebra_ns *zns, } if (!found) - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; zevpn = zebra_evpn_lookup(vxl->vni); if (p_zevpn) *p_zevpn = zevpn; - return ZNS_WALK_STOP; + return NS_WALK_STOP; } /* @@ -799,8 +801,8 @@ zebra_evpn_t *zebra_evpn_from_svi(struct interface *ifp, in_param.zif = zif; p_zevpn = &zevpn; /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */ - zebra_ns_list_walk(zebra_evpn_from_svi_zns, (void *)&in_param, - (void **)p_zevpn); + ns_walk_func(zebra_evpn_from_svi_ns, (void *)&in_param, + (void **)p_zevpn); return zevpn; } diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 13864cd429..6462daf687 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -153,20 +153,25 @@ static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete) /* During zebra shutdown, do partial cleanup while the async dataplane * is still running. */ -int zebra_ns_early_shutdown(struct ns *ns) +int zebra_ns_early_shutdown(struct ns *ns, + void *param_in __attribute__((unused)), + void **param_out __attribute__((unused))) { struct zebra_ns *zns = ns->info; if (zns == NULL) return 0; - return zebra_ns_disable_internal(zns, false); + zebra_ns_disable_internal(zns, false); + return NS_WALK_CONTINUE; } /* During zebra shutdown, do final cleanup * after all dataplane work is complete. */ -int zebra_ns_final_shutdown(struct ns *ns) +int zebra_ns_final_shutdown(struct ns *ns, + void *param_in __attribute__((unused)), + void **param_out __attribute__((unused))) { struct zebra_ns *zns = ns->info; @@ -175,7 +180,7 @@ int zebra_ns_final_shutdown(struct ns *ns) kernel_terminate(zns, true); - return 0; + return NS_WALK_CONTINUE; } int zebra_ns_init(const char *optional_default_name) @@ -233,25 +238,3 @@ int zebra_ns_config_write(struct vty *vty, struct ns *ns) vty_out(vty, " netns %s\n", ns->name); return 0; } - -void zebra_ns_list_walk(int (*exec_for_each_zns)(struct zebra_ns *zns, - void *param_in, - void **param_out), - void *param_in, - void **param_out) -{ - struct ns *ns; - struct zebra_ns *zns; - int ret; - - RB_FOREACH (ns, ns_head, &ns_tree) { - zns = (struct zebra_ns *)ns->info; - if (!zns && ns->ns_id == NS_DEFAULT) - zns = zebra_ns_lookup(ns->ns_id); - if (!zns) - continue; - ret = exec_for_each_zns(zns, param_in, param_out); - if (ret == ZNS_WALK_STOP) - return; - } -} diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index fa2fd47c25..f7d1f40782 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -67,19 +67,14 @@ struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id); int zebra_ns_init(const char *optional_default_name); int zebra_ns_enable(ns_id_t ns_id, void **info); int zebra_ns_disabled(struct ns *ns); -int zebra_ns_early_shutdown(struct ns *ns); -int zebra_ns_final_shutdown(struct ns *ns); - +int zebra_ns_early_shutdown(struct ns *ns, + void *param_in __attribute__((unused)), + void **param_out __attribute__((unused))); +int zebra_ns_final_shutdown(struct ns *ns, + void *param_in __attribute__((unused)), + void **param_out __attribute__((unused))); int zebra_ns_config_write(struct vty *vty, struct ns *ns); -#define ZNS_WALK_CONTINUE 0 -#define ZNS_WALK_STOP 1 -void zebra_ns_list_walk(int (*exec_for_each_zns)(struct zebra_ns *zns, - void *param_in, - void **param_out), - void *param_in, - void **param_out); - #ifdef __cplusplus } #endif diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 6332854e73..61498973e9 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -782,10 +782,11 @@ static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data) vty_out(vty, "\n"); } -static int zvni_map_to_svi_ns(struct zebra_ns *zns, +static int zvni_map_to_svi_ns(struct ns *ns, void *_in_param, void **_p_ifp) { + struct zebra_ns *zns = ns->info; struct route_node *rn; struct zebra_from_svi_param *in_param = (struct zebra_from_svi_param *)_in_param; @@ -795,7 +796,7 @@ static int zvni_map_to_svi_ns(struct zebra_ns *zns, struct zebra_if *zif; if (!in_param) - return ZNS_WALK_STOP; + return NS_WALK_STOP; /* TODO: Optimize with a hash. */ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { @@ -812,10 +813,10 @@ static int zvni_map_to_svi_ns(struct zebra_ns *zns, if (vl->vid == in_param->vid) { if (p_ifp) *p_ifp = tmp_if; - return ZNS_WALK_STOP; + return NS_WALK_STOP; } } - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; } /* Map to SVI on bridge corresponding to specified VLAN. This can be one @@ -850,8 +851,8 @@ struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if) in_param.zif = NULL; p_ifp = &tmp_if; /* Identify corresponding VLAN interface. */ - zebra_ns_list_walk(zvni_map_to_svi_ns, (void *)&in_param, - (void **)p_ifp); + ns_walk_func(zvni_map_to_svi_ns, (void *)&in_param, + (void **)p_ifp); return tmp_if; } @@ -865,10 +866,11 @@ static int zebra_evpn_vxlan_del(zebra_evpn_t *zevpn) return zebra_evpn_del(zevpn); } -static int zevpn_build_hash_table_zns(struct zebra_ns *zns, +static int zevpn_build_hash_table_zns(struct ns *ns, void *param_in __attribute__((unused)), void **param_out __attribute__((unused))) { + struct zebra_ns *zns = ns->info; struct route_node *rn; struct interface *ifp; struct zebra_vrf *zvrf; @@ -876,7 +878,7 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns, zvrf = zebra_vrf_get_evpn(); if (!zvrf) - return ZNS_WALK_STOP; + return NS_WALK_STOP; /* Walk VxLAN interfaces and create EVPN hash. */ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { @@ -972,7 +974,7 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns, zlog_debug( "Failed to add EVPN hash, IF %s(%u) L2-VNI %u", ifp->name, ifp->ifindex, vni); - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; } if (zevpn->local_vtep_ip.s_addr != @@ -1014,7 +1016,7 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns, } } } - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; } /* @@ -1024,9 +1026,9 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns, static void zevpn_build_hash_table(void) { - zebra_ns_list_walk(zevpn_build_hash_table_zns, - (void *)NULL, - (void **)NULL); + ns_walk_func(zevpn_build_hash_table_zns, + (void *)NULL, + (void **)NULL); } /* @@ -1659,10 +1661,11 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni) return 0; } -static int zl3vni_map_to_vxlan_if_zns(struct zebra_ns *zns, - void *_zl3vni, - void **_pifp) +static int zl3vni_map_to_vxlan_if_ns(struct ns *ns, + void *_zl3vni, + void **_pifp) { + struct zebra_ns *zns = ns->info; zebra_l3vni_t *zl3vni = (zebra_l3vni_t *)_zl3vni; struct route_node *rn = NULL; struct interface *ifp = NULL; @@ -1671,7 +1674,7 @@ static int zl3vni_map_to_vxlan_if_zns(struct zebra_ns *zns, zvrf = zebra_vrf_get_evpn(); if (!zvrf) - return ZNS_WALK_STOP; + return NS_WALK_STOP; /* loop through all vxlan-interface */ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { @@ -1705,10 +1708,10 @@ static int zl3vni_map_to_vxlan_if_zns(struct zebra_ns *zns, zl3vni->local_vtep_ip = vxl->vtep_ip; if (_pifp) *_pifp = (void *)ifp; - return ZNS_WALK_STOP; + return NS_WALK_STOP; } - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; } struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni) @@ -1718,8 +1721,8 @@ struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni) p_ifp = &ifp; - zebra_ns_list_walk(zl3vni_map_to_vxlan_if_zns, - (void *)zl3vni, (void **)p_ifp); + ns_walk_func(zl3vni_map_to_vxlan_if_ns, + (void *)zl3vni, (void **)p_ifp); return ifp; } @@ -5521,20 +5524,24 @@ stream_failure: return; } -static int macfdb_read_zns(struct zebra_ns *zns, - void *_in_param __attribute__((unused)), - void **out_param __attribute__((unused))) +static int macfdb_read_ns(struct ns *ns, + void *_in_param __attribute__((unused)), + void **out_param __attribute__((unused))) { + struct zebra_ns *zns = ns->info; + macfdb_read(zns); - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; } -static int neigh_read_zns(struct zebra_ns *zns, - void *_in_param __attribute__((unused)), - void **out_param __attribute__((unused))) +static int neigh_read_ns(struct ns *ns, + void *_in_param __attribute__((unused)), + void **out_param __attribute__((unused))) { + struct zebra_ns *zns = ns->info; + neigh_read(zns); - return ZNS_WALK_CONTINUE; + return NS_WALK_CONTINUE; } /* @@ -5588,10 +5595,10 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) zebra_evpn_gw_macip_add_for_evpn_hash, NULL); /* Read the MAC FDB */ - zebra_ns_list_walk(macfdb_read_zns, NULL, NULL); + ns_walk_func(macfdb_read_ns, NULL, NULL); /* Read neighbors */ - zebra_ns_list_walk(neigh_read_zns, NULL, NULL); + ns_walk_func(neigh_read_ns, NULL, NULL); } else { /* Cleanup VTEPs for all EVPNs - uninstall from * kernel and free entries. -- cgit v1.2.3