summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 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 */