diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 660fad6530..65fc8789f9 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -302,7 +302,7 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) during bootstrap. */ static int netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { int len; struct ifinfomsg *ifi; @@ -403,7 +403,7 @@ interface_lookup_netlink (struct zebra_ns *zns) ret = netlink_request (AF_PACKET, RTM_GETLINK, &zns->netlink_cmd); if (ret < 0) return ret; - ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0); + ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0, 1); if (ret < 0) return ret; @@ -411,7 +411,7 @@ interface_lookup_netlink (struct zebra_ns *zns) ret = netlink_request (AF_INET, RTM_GETADDR, &zns->netlink_cmd); if (ret < 0) return ret; - ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0); + ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0, 1); if (ret < 0) return ret; @@ -419,7 +419,7 @@ interface_lookup_netlink (struct zebra_ns *zns) ret = netlink_request (AF_INET6, RTM_GETADDR, &zns->netlink_cmd); if (ret < 0) return ret; - ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0); + ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0, 1); if (ret < 0) return ret; @@ -475,7 +475,7 @@ netlink_address (int cmd, int family, struct interface *ifp, addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label, strlen (ifc->label) + 1); - return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns); + return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); } int @@ -492,7 +492,7 @@ kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc) int netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { int len; struct ifaddrmsg *ifa; @@ -630,7 +630,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h, int netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { int len; struct ifinfomsg *ifi; diff --git a/zebra/if_netlink.h b/zebra/if_netlink.h index aac67916c0..6fa39ccab2 100644 --- a/zebra/if_netlink.h +++ b/zebra/if_netlink.h @@ -25,9 +25,9 @@ #ifdef HAVE_NETLINK extern int netlink_interface_addr (struct sockaddr_nl *snl, - struct nlmsghdr *h, ns_id_t ns_id); + struct nlmsghdr *h, ns_id_t ns_id, int startup); extern int netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id); + ns_id_t ns_id, int startup); extern int interface_lookup_netlink (struct zebra_ns *zns); #endif /* HAVE_NETLINK */ diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 058d14481e..c9c2d90eac 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -125,7 +125,7 @@ extern struct zebra_privs_t zserv_privs; int netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { zlog_warn ("netlink_talk: ignoring message type 0x%04x NS %u", h->nlmsg_type, ns_id); @@ -239,7 +239,7 @@ netlink_socket (struct nlsock *nl, unsigned long groups, ns_id_t ns_id) static int netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { /* JF: Ignore messages that aren't from the kernel */ if ( snl->nl_pid != 0 ) @@ -251,22 +251,22 @@ netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h, switch (h->nlmsg_type) { case RTM_NEWROUTE: - return netlink_route_change (snl, h, ns_id); + return netlink_route_change (snl, h, ns_id, startup); break; case RTM_DELROUTE: - return netlink_route_change (snl, h, ns_id); + return netlink_route_change (snl, h, ns_id, startup); break; case RTM_NEWLINK: - return netlink_link_change (snl, h, ns_id); + return netlink_link_change (snl, h, ns_id, startup); break; case RTM_DELLINK: - return netlink_link_change (snl, h, ns_id); + return netlink_link_change (snl, h, ns_id, startup); break; case RTM_NEWADDR: - return netlink_interface_addr (snl, h, ns_id); + return netlink_interface_addr (snl, h, ns_id, startup); break; case RTM_DELADDR: - return netlink_interface_addr (snl, h, ns_id); + return netlink_interface_addr (snl, h, ns_id, startup); break; default: zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type, @@ -280,7 +280,7 @@ 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); + netlink_parse_info (netlink_information_fetch, &zns->netlink, zns, 5, 0); zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns, zns->netlink.sock); @@ -444,12 +444,23 @@ nl_rttype_to_str (u_char rttype) return lookup (rttype_str, rttype); } -/* Receive message from netlink interface and pass those information - to the given function. */ +/* + * netlink_parse_info + * + * Receive message from netlink interface and pass those information + * to the given function. + * + * filter -> Function to call to read the results + * nl -> netlink socket information + * zns -> The zebra namespace data + * count -> How many we should read in, 0 means as much as possible + * startup -> Are we reading in under startup conditions? passed to + * the filter. + */ int netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, - ns_id_t), - struct nlsock *nl, struct zebra_ns *zns, int count) + ns_id_t, int), + struct nlsock *nl, struct zebra_ns *zns, int count, int startup) { int status; int ret = 0; @@ -613,7 +624,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, continue; } - error = (*filter) (&snl, h, zns->ns_id); + error = (*filter) (&snl, h, zns->ns_id, startup); if (error < 0) { zlog (NULL, LOG_ERR, "%s filter function error", nl->name); @@ -637,11 +648,23 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, return ret; } -/* sendmsg() to netlink socket then recvmsg(). */ +/* + * netlink_talk + * + * sendmsg() to netlink socket then recvmsg(). + * Calls netlink_parse_info to parse returned data + * + * filter -> The filter to read final results from kernel + * nlmsghdr -> The data to send to the kernel + * nl -> The netlink socket information + * zns -> The zebra namespace information + * startup -> Are we reading in under startup conditions + * This is passed through eventually to filter. + */ int netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, - ns_id_t), - struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns) + ns_id_t, int startup), + struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, int startup) { int status; struct sockaddr_nl snl; @@ -697,7 +720,7 @@ netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, * Get reply from netlink socket. * The reply should either be an acknowlegement or an error. */ - return netlink_parse_info (filter, nl, zns, 0); + return netlink_parse_info (filter, nl, zns, 0, startup); } /* Get type specified information from netlink. */ diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index f17f1380c2..adbcf71f63 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -44,14 +44,15 @@ extern const char * nl_family_to_str (u_char family); extern const char * nl_rttype_to_str (u_char rttype); extern int netlink_parse_info (int (*filter) (struct sockaddr_nl *, - struct nlmsghdr *, ns_id_t), struct nlsock *nl, - struct zebra_ns *zns, int count); + struct nlmsghdr *, ns_id_t, int), + struct nlsock *nl, struct zebra_ns *zns, + int count, int startup); extern int netlink_talk_filter (struct sockaddr_nl *, struct nlmsghdr *, - ns_id_t); + ns_id_t, int startup); extern int netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, - ns_id_t), + ns_id_t, int startup), struct nlmsghdr *n, struct nlsock *nl, - struct zebra_ns *zns); + struct zebra_ns *zns, int startup); extern int netlink_request (int family, int type, struct nlsock *nl); #endif /* HAVE_NETLINK */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index d88dc05b28..7eacec6958 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -127,7 +127,7 @@ vrf_lookup_by_table (u_int32_t table_id) /* Looking up routing table by netlink interface. */ static int netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { int len; struct rtmsg *rtm; @@ -321,7 +321,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, /* Routing information change from the kernel. */ static int netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { int len; struct rtmsg *rtm; @@ -545,7 +545,7 @@ static struct mcast_route_data *mroute = NULL; static int netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { int len; struct rtmsg *rtm; @@ -629,7 +629,7 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h int netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id) + ns_id_t ns_id, int startup) { int len; vrf_id_t vrf_id = ns_id; @@ -665,10 +665,10 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, switch (rtm->rtm_type) { case RTN_UNICAST: - netlink_route_change_read_unicast (snl, h, ns_id); + netlink_route_change_read_unicast (snl, h, ns_id, startup); break; case RTN_MULTICAST: - netlink_route_change_read_multicast (snl, h, ns_id); + netlink_route_change_read_multicast (snl, h, ns_id, startup); break; default: return 0; @@ -689,7 +689,7 @@ netlink_route_read (struct zebra_ns *zns) ret = netlink_request (AF_INET, RTM_GETROUTE, &zns->netlink_cmd); if (ret < 0) return ret; - ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns, 0); + ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns, 0, 1); if (ret < 0) return ret; @@ -697,7 +697,7 @@ netlink_route_read (struct zebra_ns *zns) ret = netlink_request (AF_INET6, RTM_GETROUTE, &zns->netlink_cmd); if (ret < 0) return ret; - ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns, 0); + ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns, 0, 1); if (ret < 0) return ret; @@ -1244,7 +1244,7 @@ netlink_neigh_update (int cmd, int ifindex, uint32_t addr, char *lla, int llalen addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4); addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen); - return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns); + return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); } /* Routing table change via netlink interface. */ @@ -1542,7 +1542,7 @@ skip: snl.nl_family = AF_NETLINK; /* Talk to netlink socket. */ - return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns); + return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); } int @@ -1572,7 +1572,7 @@ kernel_get_ipmr_sg_stats (void *in) addattr_l (&req.n, sizeof (req), RTA_SRC, &mroute->sg.src.s_addr, 4); addattr_l (&req.n, sizeof (req), RTA_DST, &mroute->sg.grp.s_addr, 4); - suc = netlink_talk (netlink_route_change_read_multicast, &req.n, &zns->netlink_cmd, zns); + suc = netlink_talk (netlink_route_change_read_multicast, &req.n, &zns->netlink_cmd, zns, 0); mroute = NULL; return suc; @@ -1766,7 +1766,7 @@ netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp) } /* Talk to netlink socket. */ - return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns); + return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); } /* diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 7183525fba..93ee622e35 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -34,7 +34,7 @@ extern int netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp); extern int netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, - ns_id_t ns_id); + ns_id_t ns_id, int startup); extern int netlink_route_read (struct zebra_ns *zns); #endif /* HAVE_NETLINK */