summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-01-27 19:33:08 +0100
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-03-01 14:08:05 +0100
commit936ebf0a2dd70f59bf846bad9f1a0fe04c87e37e (patch)
tree2404d340c89ffb565afc6355130f149bbd9d055d
parentMerge pull request #226 from donaldsharp/evpn_fix (diff)
downloadfrr-936ebf0a2dd70f59bf846bad9f1a0fe04c87e37e.tar.xz
frr-936ebf0a2dd70f59bf846bad9f1a0fe04c87e37e.zip
zebra: Add knowledge of whether or not we are acting under startup conditions
The reading if unicast routes from the kernel acts subtly differently between reading in the routes from the kernel on startup and reading a new route or getting a response for a route. Add startup flag(currently ignored) so that we can start consolidating the functionality. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
-rw-r--r--zebra/if_netlink.c14
-rw-r--r--zebra/if_netlink.h4
-rw-r--r--zebra/kernel_netlink.c59
-rw-r--r--zebra/kernel_netlink.h11
-rw-r--r--zebra/rt_netlink.c24
-rw-r--r--zebra/rt_netlink.h2
6 files changed, 69 insertions, 45 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 660fad653..65fc8789f 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 aac67916c..6fa39ccab 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 058d14481..c9c2d90ea 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 f17f1380c..adbcf71f6 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 d88dc05b2..7eacec695 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 7183525fb..93ee622e3 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 */