From 85a75f1e775be73178d1b292ec0866fb336ddf2a Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Wed, 12 Sep 2018 14:59:57 -0400 Subject: [PATCH] zebra: Start abstraction of zebra_dplane_info for context passing Reduce or eliminate use of global zebra_ns structs in a couple of netlink/kernel code paths, so that those paths can potentially be made asynch eventually. Signed-off-by: Mark Stapp Signed-off-by: Donald Sharp --- zebra/if_netlink.c | 31 +++++++++++++--------- zebra/kernel_netlink.c | 21 ++++++++++----- zebra/kernel_netlink.h | 2 +- zebra/rt_netlink.c | 56 +++++++++++++++++++++++++-------------- zebra/zebra_dplane.h | 27 +++++++++++++++++++ zebra/zebra_fpm_netlink.c | 1 + zebra/zebra_netns_id.c | 3 ++- 7 files changed, 99 insertions(+), 42 deletions(-) diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 47a101e619..65d60d8448 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -698,8 +698,8 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) } /* Request for specific interface or address information from the kernel */ -static int netlink_request_intf_addr(struct zebra_ns *zns, int family, int type, - uint32_t filter_mask) +static int netlink_request_intf_addr(struct nlsock *netlink_cmd, int family, + int type, uint32_t filter_mask) { struct { struct nlmsghdr n; @@ -717,57 +717,62 @@ static int netlink_request_intf_addr(struct zebra_ns *zns, int family, int type, if (filter_mask) addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask); - return netlink_request(&zns->netlink_cmd, &req.n); + return netlink_request(netlink_cmd, &req.n); } /* Interface lookup by netlink socket. */ int interface_lookup_netlink(struct zebra_ns *zns) { int ret; + struct zebra_dplane_info dp_info; + struct nlsock *netlink_cmd = &zns->netlink_cmd; + + /* Capture key info from ns struct */ + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); /* Get interface information. */ - ret = netlink_request_intf_addr(zns, AF_PACKET, RTM_GETLINK, 0); + ret = netlink_request_intf_addr(netlink_cmd, AF_PACKET, RTM_GETLINK, 0); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0, + ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0, 1); if (ret < 0) return ret; /* Get interface information - for bridge interfaces. */ - ret = netlink_request_intf_addr(zns, AF_BRIDGE, RTM_GETLINK, + ret = netlink_request_intf_addr(netlink_cmd, AF_BRIDGE, RTM_GETLINK, RTEXT_FILTER_BRVLAN); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0, + ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0, 0); if (ret < 0) return ret; /* Get interface information - for bridge interfaces. */ - ret = netlink_request_intf_addr(zns, AF_BRIDGE, RTM_GETLINK, + ret = netlink_request_intf_addr(netlink_cmd, AF_BRIDGE, RTM_GETLINK, RTEXT_FILTER_BRVLAN); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0, + ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0, 0); if (ret < 0) return ret; /* Get IPv4 address of the interfaces. */ - ret = netlink_request_intf_addr(zns, AF_INET, RTM_GETADDR, 0); + ret = netlink_request_intf_addr(netlink_cmd, AF_INET, RTM_GETADDR, 0); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_interface_addr, &zns->netlink_cmd, zns, + ret = netlink_parse_info(netlink_interface_addr, netlink_cmd, &dp_info, 0, 1); if (ret < 0) return ret; /* Get IPv6 address of the interfaces. */ - ret = netlink_request_intf_addr(zns, AF_INET6, RTM_GETADDR, 0); + ret = netlink_request_intf_addr(netlink_cmd, AF_INET6, RTM_GETADDR, 0); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_interface_addr, &zns->netlink_cmd, zns, + ret = netlink_parse_info(netlink_interface_addr, netlink_cmd, &dp_info, 0, 1); if (ret < 0) return ret; diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index d35230d7bd..c8ea8ae445 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -373,7 +373,13 @@ static long netlink_read_file(char *buf, const char *fname) static int kernel_read(struct thread *thread) { struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread); - netlink_parse_info(netlink_information_fetch, &zns->netlink, zns, 5, 0); + struct zebra_dplane_info dp_info; + + /* Capture key info from ns struct */ + zebra_dplane_info_from_zns(&dp_info, zns, false); + + netlink_parse_info(netlink_information_fetch, &zns->netlink, &dp_info, + 5, 0); zns->t_netlink = NULL; thread_add_read(zebrad.master, kernel_read, zns, zns->netlink.sock, &zns->t_netlink); @@ -672,8 +678,8 @@ static void netlink_parse_extended_ack(struct nlmsghdr *h) * the filter. */ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), - struct nlsock *nl, struct zebra_ns *zns, int count, - int startup) + struct nlsock *nl, struct zebra_dplane_info *zns, + int count, int startup) { int status; int ret = 0; @@ -811,7 +817,7 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), /* Deal with errors that occur because of races * in link handling */ - if (nl == &zns->netlink_cmd + if (zns->is_cmd && ((msg_type == RTM_DELROUTE && (-errnum == ENODEV || -errnum == ESRCH)) @@ -838,8 +844,7 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), * so do not log these as an error. */ if (msg_type == RTM_DELNEIGH - || (nl == &zns->netlink_cmd - && msg_type == RTM_NEWROUTE + || (zns->is_cmd && msg_type == RTM_NEWROUTE && (-errnum == ESRCH || -errnum == ENETUNREACH))) { /* This is known to happen in some @@ -935,6 +940,7 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), struct iovec iov; struct msghdr msg; int save_errno = 0; + struct zebra_dplane_info dp_info; memset(&snl, 0, sizeof snl); memset(&iov, 0, sizeof iov); @@ -981,7 +987,8 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), * Get reply from netlink socket. * The reply should either be an acknowlegement or an error. */ - return netlink_parse_info(filter, nl, zns, 0, startup); + zebra_dplane_info_from_zns(&dp_info, zns, (nl == &(zns->netlink_cmd))); + return netlink_parse_info(filter, nl, &dp_info, 0, startup); } /* Issue request message to kernel via netlink socket. GET messages diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index af0cc83f4a..d78958d72e 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -52,7 +52,7 @@ extern bool netlink_read; extern void netlink_read_init(const char *fname); #endif /* HANDLE_NETLINK_FUZZING */ extern int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), - struct nlsock *nl, struct zebra_ns *zns, + struct nlsock *nl, struct zebra_dplane_info *zns, int count, int startup); extern int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns, int startup); extern int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index fe42ab5be6..2e2fd99312 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -890,13 +890,16 @@ static int netlink_request_route(struct zebra_ns *zns, int family, int type) int netlink_route_read(struct zebra_ns *zns) { int ret; + struct zebra_dplane_info dp_info; + + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); /* Get IPv4 routing table. */ ret = netlink_request_route(zns, AF_INET, RTM_GETROUTE); if (ret < 0) return ret; ret = netlink_parse_info(netlink_route_change_read_unicast, - &zns->netlink_cmd, zns, 0, 1); + &zns->netlink_cmd, &dp_info, 0, 1); if (ret < 0) return ret; @@ -905,7 +908,7 @@ int netlink_route_read(struct zebra_ns *zns) if (ret < 0) return ret; ret = netlink_parse_info(netlink_route_change_read_unicast, - &zns->netlink_cmd, zns, 0, 1); + &zns->netlink_cmd, &dp_info, 0, 1); if (ret < 0) return ret; @@ -2102,8 +2105,8 @@ static int netlink_macfdb_table(struct nlmsghdr *h, ns_id_t ns_id, int startup) } /* Request for MAC FDB information from the kernel */ -static int netlink_request_macs(struct zebra_ns *zns, int family, int type, - ifindex_t master_ifindex) +static int netlink_request_macs(struct nlsock *netlink_cmd, int family, + int type, ifindex_t master_ifindex) { struct { struct nlmsghdr n; @@ -2119,7 +2122,7 @@ static int netlink_request_macs(struct zebra_ns *zns, int family, int type, if (master_ifindex) addattr32(&req.n, sizeof(req), IFLA_MASTER, master_ifindex); - return netlink_request(&zns->netlink_cmd, &req.n); + return netlink_request(netlink_cmd, &req.n); } /* @@ -2129,15 +2132,19 @@ static int netlink_request_macs(struct zebra_ns *zns, int family, int type, int netlink_macfdb_read(struct zebra_ns *zns) { int ret; + struct zebra_dplane_info dp_info; + + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); /* Get bridge FDB table. */ - ret = netlink_request_macs(zns, AF_BRIDGE, RTM_GETNEIGH, 0); + ret = netlink_request_macs(&zns->netlink_cmd, AF_BRIDGE, RTM_GETNEIGH, + 0); if (ret < 0) return ret; /* We are reading entire table. */ filter_vlan = 0; - ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd, zns, - 0, 1); + ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd, + &dp_info, 0, 1); return ret; } @@ -2152,8 +2159,10 @@ int netlink_macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp, struct zebra_if *br_zif; struct zebra_if *zif; struct zebra_l2info_vxlan *vxl; + struct zebra_dplane_info dp_info; int ret = 0; + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); /* Save VLAN we're filtering on, if needed. */ br_zif = (struct zebra_if *)br_if->info; @@ -2164,12 +2173,12 @@ int netlink_macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp, /* Get bridge FDB table for specific bridge - we do the VLAN filtering. */ - ret = netlink_request_macs(zns, AF_BRIDGE, RTM_GETNEIGH, + ret = netlink_request_macs(&zns->netlink_cmd, AF_BRIDGE, RTM_GETNEIGH, br_if->ifindex); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd, zns, - 0, 0); + ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd, + &dp_info, 0, 0); /* Reset VLAN filter. */ filter_vlan = 0; @@ -2421,8 +2430,8 @@ static int netlink_neigh_table(struct nlmsghdr *h, ns_id_t ns_id, int startup) } /* Request for IP neighbor information from the kernel */ -static int netlink_request_neigh(struct zebra_ns *zns, int family, int type, - ifindex_t ifindex) +static int netlink_request_neigh(struct nlsock *netlink_cmd, int family, + int type, ifindex_t ifindex) { struct { struct nlmsghdr n; @@ -2438,7 +2447,7 @@ static int netlink_request_neigh(struct zebra_ns *zns, int family, int type, if (ifindex) addattr32(&req.n, sizeof(req), NDA_IFINDEX, ifindex); - return netlink_request(&zns->netlink_cmd, &req.n); + return netlink_request(netlink_cmd, &req.n); } /* @@ -2448,13 +2457,17 @@ static int netlink_request_neigh(struct zebra_ns *zns, int family, int type, int netlink_neigh_read(struct zebra_ns *zns) { int ret; + struct zebra_dplane_info dp_info; + + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); /* Get IP neighbor table. */ - ret = netlink_request_neigh(zns, AF_UNSPEC, RTM_GETNEIGH, 0); + ret = netlink_request_neigh(&zns->netlink_cmd, AF_UNSPEC, RTM_GETNEIGH, + 0); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd, zns, 0, - 1); + ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd, + &dp_info, 0, 1); return ret; } @@ -2466,13 +2479,16 @@ int netlink_neigh_read(struct zebra_ns *zns) int netlink_neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if) { int ret = 0; + struct zebra_dplane_info dp_info; + + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); - ret = netlink_request_neigh(zns, AF_UNSPEC, RTM_GETNEIGH, + ret = netlink_request_neigh(&zns->netlink_cmd, AF_UNSPEC, RTM_GETNEIGH, vlan_if->ifindex); if (ret < 0) return ret; - ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd, zns, 0, - 0); + ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd, + &dp_info, 0, 0); return ret; } diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 27854e79d3..7cbef7453c 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -32,6 +32,33 @@ * context. */ +/* Key netlink info from zebra ns */ +struct zebra_dplane_info { + ns_id_t ns_id; + +#if defined(HAVE_NETLINK) + uint32_t nl_pid; + bool is_cmd; +#endif +}; + +/* Utility to fill in zns info from main zns struct */ +static inline void +zebra_dplane_info_from_zns(struct zebra_dplane_info *zns_info, + const struct zebra_ns *zns, bool is_cmd) +{ + zns_info->ns_id = zns->ns_id; + +#if defined(HAVE_NETLINK) + zns_info->is_cmd = is_cmd; + if (is_cmd) { + zns_info->nl_pid = zns->netlink_cmd.snl.nl_pid; + } else { + zns_info->nl_pid = zns->netlink.snl.nl_pid; + } +#endif /* NETLINK */ +} + /* * Enqueue a route install or update for the dataplane. */ diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index c27884ec48..207cbc0992 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -32,6 +32,7 @@ #include "prefix.h" #include "zebra/zserv.h" +#include "zebra/zebra_dplane.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/kernel_netlink.h" diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index b26c0515f1..600d1d55c6 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -24,13 +24,14 @@ #include "log.h" #include "lib_errors.h" +#include "zebra/rib.h" +#include "zebra/zebra_dplane.h" #if defined(HAVE_NETLINK) #include #include #include -#include "rib.h" #include "zebra_ns.h" #include "kernel_netlink.h" #endif /* defined(HAVE_NETLINK) */ -- 2.39.5