diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/if_netlink.c | 2 | ||||
-rw-r--r-- | zebra/kernel_netlink.c | 28 | ||||
-rw-r--r-- | zebra/kernel_netlink.h | 2 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 79 |
4 files changed, 95 insertions, 16 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 3665ad061..d55385054 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -433,7 +433,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 (&req.n, &zns->netlink_cmd, zns); + return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns); } int diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 9142d4d15..20c4b5afe 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -95,6 +95,21 @@ static const struct message rtproto_str[] = { {0, NULL} }; +static const struct message family_str[] = { + {AF_INET, "ipv4"}, + {AF_INET6, "ipv6"}, + {AF_BRIDGE, "bridge"}, + {RTNL_FAMILY_IPMR, "ipv4MR"}, + {RTNL_FAMILY_IP6MR, "ipv6MR"}, + {0, NULL}, +}; + +static const struct message rttype_str[] = { + {RTN_UNICAST, "unicast"}, + {RTN_MULTICAST, "multicast"}, + {0, NULL}, +}; + extern struct thread_master *master; extern u_int32_t nl_rcvbufsize; @@ -398,6 +413,19 @@ nl_rtproto_to_str (u_char rtproto) { return lookup (rtproto_str, rtproto); } + +const char * +nl_family_to_str (u_char family) +{ + return lookup (family_str, family); +} + +const char * +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. */ int diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index f97e6e8cc..f17f1380c 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -40,6 +40,8 @@ extern struct rtattr * rta_nest(struct rtattr *rta, int maxlen, int type); extern int rta_nest_end(struct rtattr *rta, struct rtattr *nest); extern const char * nl_msg_type_to_str (uint16_t msg_type); extern const char * nl_rtproto_to_str (u_char rtproto); +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, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index a351b457c..0fd29a5ef 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -303,14 +303,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, return 0; } -static const struct message family_str[] = { - {AF_INET, "ipv4"}, - {AF_INET6, "ipv6"}, - {RTNL_FAMILY_IPMR, "ipv4MR"}, - {RTNL_FAMILY_IP6MR, "ipv6MR"}, - {0, NULL}, -}; - /* Routing information change from the kernel. */ static int netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, @@ -421,7 +413,7 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, { char buf[PREFIX_STRLEN]; zlog_debug ("%s %s vrf %u", - h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE", + nl_msg_type_to_str (h->nlmsg_type), prefix2str (&p, buf, sizeof(buf)), vrf_id); } @@ -508,7 +500,7 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, { char buf[PREFIX_STRLEN]; zlog_debug ("%s %s vrf %u", - h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE", + nl_msg_type_to_str (h->nlmsg_type), prefix2str (&p, buf, sizeof(buf)), vrf_id); } @@ -529,8 +521,20 @@ 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; + int iif = 0; + int count; + int oif[256]; + int oif_count = 0; + 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; rtm = NLMSG_DATA (h); @@ -539,6 +543,52 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h memset (tb, 0, sizeof tb); netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len); + if (tb[RTA_IIF]) + iif = *(int *)RTA_DATA (tb[RTA_IIF]); + + if (tb[RTA_SRC]) + sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]); + + if (tb[RTA_DST]) + sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]); + + if (tb[RTA_EXPIRES]) + lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]); + + if (tb[RTA_MULTIPATH]) + { + struct rtnexthop *rtnh = + (struct rtnexthop *)RTA_DATA (tb[RTA_MULTIPATH]); + + len = RTA_PAYLOAD (tb[RTA_MULTIPATH]); + for (;;) + { + if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len) + break; + + oif[oif_count] = rtnh->rtnh_ifindex; + oif_count++; + + len -= NLMSG_ALIGN (rtnh->rtnh_len); + rtnh = RTNH_NEXT (rtnh); + } + } + + if (IS_ZEBRA_DEBUG_KERNEL) + { + strcpy (sbuf, inet_ntoa (sg.src)); + strcpy (gbuf, inet_ntoa (sg.grp)); + for (count = 0; count < oif_count; count++) + { + struct interface *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); + } return 0; } @@ -562,12 +612,11 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, /* Connected route. */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("%s %s %s proto %s vrf %u", - h->nlmsg_type == - RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE", - lookup (family_str, rtm->rtm_family), - rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast", + nl_msg_type_to_str (h->nlmsg_type), + nl_family_to_str (rtm->rtm_family), + nl_rttype_to_str (rtm->rtm_type), nl_rtproto_to_str (rtm->rtm_protocol), - vrf_id); + vrf_id); /* We don't care about change notifications for the MPLS table. */ /* TODO: Revisit this. */ |