summaryrefslogtreecommitdiff
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/rt_netlink.c')
-rw-r--r--zebra/rt_netlink.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 913d1d5770..d2781f4c4e 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -55,6 +55,8 @@
#include "zebra/zebra_mpls.h"
#include "zebra/kernel_netlink.h"
#include "zebra/rt_netlink.h"
+#include "zebra/zebra_mroute.h"
+
/* TODO - Temporary definitions, need to refine. */
#ifndef AF_MPLS
@@ -88,6 +90,10 @@
#ifndef MPLS_IPTUNNEL_DST
#define MPLS_IPTUNNEL_DST 1
#endif
+
+#ifndef NDA_MASTER
+#define NDA_MASTER 9
+#endif
/* End of temporary definitions */
struct gw_family_t
@@ -520,15 +526,17 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
return 0;
}
+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)
{
int len;
- unsigned long long lastused = 0;
struct rtmsg *rtm;
struct rtattr *tb[RTA_MAX + 1];
- struct prefix_sg sg;
+ struct mcast_route_data *m;
+ struct mcast_route_data mr;
int iif = 0;
int count;
int oif[256];
@@ -536,10 +544,16 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h
char sbuf[40];
char gbuf[40];
char oif_list[256] = "\0";
- memset (&sg, 0, sizeof (sg));
- sg.family = IANA_AFI_IPMR;
vrf_id_t vrf = ns_id;
+ if (mroute)
+ m = mroute;
+ else
+ {
+ memset (&mr, 0, sizeof (mr));
+ m = &mr;
+ }
+
rtm = NLMSG_DATA (h);
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
@@ -551,13 +565,13 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h
iif = *(int *)RTA_DATA (tb[RTA_IIF]);
if (tb[RTA_SRC])
- sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]);
+ m->sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]);
if (tb[RTA_DST])
- sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]);
+ m->sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]);
if ((RTA_EXPIRES <= RTA_MAX) && tb[RTA_EXPIRES])
- lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]);
+ m->lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]);
if (tb[RTA_MULTIPATH])
{
@@ -580,18 +594,20 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h
if (IS_ZEBRA_DEBUG_KERNEL)
{
- strcpy (sbuf, inet_ntoa (sg.src));
- strcpy (gbuf, inet_ntoa (sg.grp));
+ struct interface *ifp;
+ strcpy (sbuf, inet_ntoa (m->sg.src));
+ strcpy (gbuf, inet_ntoa (m->sg.grp));
for (count = 0; count < oif_count; count++)
{
- struct interface *ifp = if_lookup_by_index_vrf (oif[count], vrf);
+ ifp = if_lookup_by_index_vrf (oif[count], vrf);
char temp[256];
sprintf (temp, "%s ", ifp->name);
strcat (oif_list, temp);
}
- zlog_debug ("MCAST %s (%s,%s) IIF: %d OIF: %s jiffies: %lld",
- nl_msg_type_to_str (h->nlmsg_type), sbuf, gbuf, iif, oif_list, lastused);
+ ifp = if_lookup_by_index_vrf (iif, vrf);
+ zlog_debug ("MCAST %s (%s,%s) IIF: %s OIF: %s jiffies: %lld",
+ nl_msg_type_to_str(h->nlmsg_type), sbuf, gbuf, ifp->name, oif_list, m->lastused);
}
return 0;
}
@@ -1510,6 +1526,39 @@ skip:
}
int
+kernel_get_ipmr_sg_stats (void *in)
+{
+ int suc = 0;
+ struct mcast_route_data *mr = (struct mcast_route_data *)in;
+ struct {
+ struct nlmsghdr n;
+ struct ndmsg ndm;
+ char buf[256];
+ } req;
+
+ mroute = mr;
+ struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
+
+ memset(&req.n, 0, sizeof(req.n));
+ memset(&req.ndm, 0, sizeof(req.ndm));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.ndm.ndm_family = AF_INET;
+ req.n.nlmsg_type = RTM_GETROUTE;
+
+ addattr_l (&req.n, sizeof (req), RTA_IIF, &mroute->ifindex, 4);
+ addattr_l (&req.n, sizeof (req), RTA_OIF, &mroute->ifindex, 4);
+ 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);
+
+ mroute = NULL;
+ return suc;
+}
+
+int
kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
{
if (!old && new)