mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 09:00:55 +00:00
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>
This commit is contained in:
parent
f9c5f9f771
commit
936ebf0a2d
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user