#include "zebra/rt_netlink.h"
#include "zebra/zebra_mroute.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_errors.h"
#ifndef AF_MPLS
#define AF_MPLS 28
|| (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP)
|| (proto == RTPROT_LDP) || (proto == RTPROT_BABEL)
|| (proto == RTPROT_RIP) || (proto == RTPROT_SHARP)
- || (proto == RTPROT_PBR)) {
+ || (proto == RTPROT_PBR) || (proto == RTPROT_OPENFABRIC)) {
return 1;
}
case ZEBRA_ROUTE_PBR:
proto = RTPROT_PBR;
break;
+ case ZEBRA_ROUTE_OPENFABRIC:
+ proto = RTPROT_OPENFABRIC;
+ break;
default:
/*
* When a user adds a new protocol this will show up
* is intentionally a warn because we should see
* this as part of development of a new protocol
*/
- zlog_warn("%s: Please add this protocol(%d) to proper rt_netlink.c handling",
- __PRETTY_FUNCTION__, proto);
+ zlog_debug(
+ "%s: Please add this protocol(%d) to proper rt_netlink.c handling",
+ __PRETTY_FUNCTION__, proto);
proto = RTPROT_ZEBRA;
break;
}
case RTPROT_PBR:
proto = ZEBRA_ROUTE_PBR;
break;
+ case RTPROT_OPENFABRIC:
+ proto = ZEBRA_ROUTE_OPENFABRIC;
+ break;
default:
/*
* When a user adds a new protocol this will show up
* is intentionally a warn because we should see
* this as part of development of a new protocol
*/
- zlog_warn("%s: Please add this protocol(%d) to proper rt_netlink.c handling",
- __PRETTY_FUNCTION__,
- proto);
+ zlog_debug(
+ "%s: Please add this protocol(%d) to proper rt_netlink.c handling",
+ __PRETTY_FUNCTION__, proto);
proto = ZEBRA_ROUTE_KERNEL;
break;
}
return VRF_DEFAULT;
}
+/**
+ * @parse_encap_mpls() - Parses encapsulated mpls attributes
+ * @tb: Pointer to rtattr to look for nested items in.
+ * @labels: Pointer to store labels in.
+ *
+ * Return: Number of mpls labels found.
+ */
+static int parse_encap_mpls(struct rtattr *tb, mpls_label_t *labels)
+{
+ struct rtattr *tb_encap[MPLS_IPTUNNEL_MAX + 1] = {0};
+ mpls_lse_t *lses = NULL;
+ int num_labels = 0;
+ uint32_t ttl = 0;
+ uint32_t bos = 0;
+ uint32_t exp = 0;
+ mpls_label_t label = 0;
+
+ netlink_parse_rtattr_nested(tb_encap, MPLS_IPTUNNEL_MAX, tb);
+ lses = (mpls_lse_t *)RTA_DATA(tb_encap[MPLS_IPTUNNEL_DST]);
+ while (!bos && num_labels < MPLS_MAX_LABELS) {
+ mpls_lse_decode(lses[num_labels], &label, &ttl, &exp, &bos);
+ labels[num_labels++] = label;
+ }
+
+ return num_labels;
+}
+
/* Looking up routing table by netlink interface. */
static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
int startup)
void *src = NULL; /* IPv6 srcdest source prefix */
enum blackhole_type bh_type = BLACKHOLE_UNSPEC;
+ /* MPLS labels */
+ mpls_label_t labels[MPLS_MAX_LABELS] = {0};
+ int num_labels = 0;
+
rtm = NLMSG_DATA(h);
if (startup && h->nlmsg_type != RTM_NEWROUTE)
if (rtm->rtm_src_len != 0) {
char buf[PREFIX_STRLEN];
- zlog_warn("unsupported IPv4 sourcedest route (dest %s vrf %u)",
- prefix2str(&p, buf, sizeof(buf)), vrf_id);
+ flog_warn(
+ EC_ZEBRA_UNSUPPORTED_V4_SRCDEST,
+ "unsupported IPv4 sourcedest route (dest %s vrf %u)",
+ prefix2str(&p, buf, sizeof(buf)), vrf_id);
return 0;
}
}
nh.vrf_id = nh_vrf_id;
+ if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]
+ && *(uint16_t *)RTA_DATA(tb[RTA_ENCAP_TYPE])
+ == LWTUNNEL_ENCAP_MPLS) {
+ num_labels =
+ parse_encap_mpls(tb[RTA_ENCAP], labels);
+ }
+
+ if (num_labels)
+ nexthop_add_labels(&nh, ZEBRA_LSP_STATIC,
+ num_labels, labels);
+
rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p,
&src_p, &nh, table, metric, mtu, distance, tag);
} else {
re->tag = tag;
for (;;) {
- vrf_id_t nh_vrf_id;
+ struct nexthop *nh = NULL;
+
if (len < (int)sizeof(*rtnh)
|| rtnh->rtnh_len > len)
break;
if (ifp)
nh_vrf_id = ifp->vrf_id;
else {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_INTERFACE,
"%s: Unknown interface %u specified, defaulting to VRF_DEFAULT",
__PRETTY_FUNCTION__,
index);
if (tb[RTA_GATEWAY])
gate = RTA_DATA(
tb[RTA_GATEWAY]);
+ if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]
+ && *(uint16_t *)RTA_DATA(
+ tb[RTA_ENCAP_TYPE])
+ == LWTUNNEL_ENCAP_MPLS) {
+ num_labels = parse_encap_mpls(
+ tb[RTA_ENCAP], labels);
+ }
}
if (gate) {
if (rtm->rtm_family == AF_INET) {
if (index)
- route_entry_nexthop_ipv4_ifindex_add(
+ nh = route_entry_nexthop_ipv4_ifindex_add(
re, gate,
prefsrc, index,
nh_vrf_id);
else
- route_entry_nexthop_ipv4_add(
+ nh = route_entry_nexthop_ipv4_add(
re, gate,
prefsrc,
nh_vrf_id);
} else if (rtm->rtm_family
== AF_INET6) {
if (index)
- route_entry_nexthop_ipv6_ifindex_add(
+ nh = route_entry_nexthop_ipv6_ifindex_add(
re, gate, index,
nh_vrf_id);
else
- route_entry_nexthop_ipv6_add(
+ nh = route_entry_nexthop_ipv6_add(
re, gate,
nh_vrf_id);
}
} else
- route_entry_nexthop_ifindex_add(
+ nh = route_entry_nexthop_ifindex_add(
re, index, nh_vrf_id);
+ if (nh && num_labels)
+ nexthop_add_labels(nh, ZEBRA_LSP_STATIC,
+ num_labels, labels);
+
if (rtnh->rtnh_len == 0)
break;
ifp = if_lookup_by_index(oif[count], vrf);
char temp[256];
- sprintf(temp, "%s ", ifp->name);
+ sprintf(temp, "%s(%d) ", ifp ? ifp->name : "Unknown",
+ oif[count]);
strcat(oif_list, temp);
}
struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf);
ifp = if_lookup_by_index(iif, vrf);
- zlog_debug(
- "MCAST VRF: %s(%d) %s (%s,%s) IIF: %s OIF: %s jiffies: %lld",
- zvrf->vrf->name, vrf, nl_msg_type_to_str(h->nlmsg_type),
- sbuf, gbuf, ifp->name, oif_list, m->lastused);
+ zlog_debug("MCAST VRF: %s(%d) %s (%s,%s) IIF: %s(%d) OIF: %s jiffies: %lld",
+ zvrf->vrf->name, vrf,
+ nl_msg_type_to_str(h->nlmsg_type),
+ sbuf, gbuf, ifp ? ifp->name : "Unknown", iif,
+ oif_list, m->lastused);
}
return 0;
}
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)) {
/* If this is not route add/delete message print warning. */
- zlog_warn("Kernel message: %d NS %u\n", h->nlmsg_type, ns_id);
+ zlog_debug("Kernel message: %s NS %u\n",
+ nl_msg_type_to_str(h->nlmsg_type), ns_id);
return 0;
}
- if (!(rtm->rtm_family == AF_INET || rtm->rtm_family == AF_INET6)) {
- zlog_warn(
- "Invalid address family: %u received from kernel route change: %u",
- rtm->rtm_family, h->nlmsg_type);
+ if (!(rtm->rtm_family == AF_INET ||
+ rtm->rtm_family == AF_INET6 ||
+ rtm->rtm_family == RTNL_FAMILY_IPMR )) {
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_FAMILY,
+ "Invalid address family: %u received from kernel route change: %s",
+ rtm->rtm_family, nl_msg_type_to_str(h->nlmsg_type));
return 0;
}
int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
{
+ uint32_t actual_table;
int suc = 0;
struct mcast_route_data *mr = (struct mcast_route_data *)in;
struct {
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);
- addattr_l(&req.n, sizeof(req), RTA_TABLE, &zvrf->table_id, 4);
+ /*
+ * What?
+ *
+ * So during the namespace cleanup we started storing
+ * the zvrf table_id for the default table as RT_TABLE_MAIN
+ * which is what the normal routing table for ip routing is.
+ * This change caused this to break our lookups of sg data
+ * because prior to this change the zvrf->table_id was 0
+ * and when the pim multicast kernel code saw a 0,
+ * it was auto-translated to RT_TABLE_DEFAULT. But since
+ * we are now passing in RT_TABLE_MAIN there is no auto-translation
+ * and the kernel goes screw you and the delicious cookies you
+ * are trying to give me. So now we have this little hack.
+ */
+ actual_table = (zvrf->table_id == RT_TABLE_MAIN) ? RT_TABLE_DEFAULT :
+ zvrf->table_id;
+ addattr_l(&req.n, sizeof(req), RTA_TABLE, &actual_table, 4);
suc = netlink_talk(netlink_route_change_read_multicast, &req.n,
&zns->netlink_cmd, zns, 0);
return suc;
}
-enum dp_req_result kernel_route_rib(struct route_node *rn,
- const struct prefix *p,
- const struct prefix *src_p,
- struct route_entry *old,
- struct route_entry *new)
+enum zebra_dplane_result kernel_route_rib(struct route_node *rn,
+ const struct prefix *p,
+ const struct prefix *src_p,
+ struct route_entry *old,
+ struct route_entry *new)
{
int ret = 0;
new, 0);
}
kernel_route_rib_pass_fail(rn, p, new,
- (!ret) ? DP_INSTALL_SUCCESS
- : DP_INSTALL_FAILURE);
- return DP_REQUEST_SUCCESS;
+ (!ret) ? ZEBRA_DPLANE_INSTALL_SUCCESS
+ : ZEBRA_DPLANE_INSTALL_FAILURE);
+ return ZEBRA_DPLANE_REQUEST_SUCCESS;
}
if (old) {
ret = netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0);
kernel_route_rib_pass_fail(rn, p, old,
- (!ret) ? DP_DELETE_SUCCESS
- : DP_DELETE_FAILURE);
+ (!ret) ? ZEBRA_DPLANE_DELETE_SUCCESS
+ : ZEBRA_DPLANE_DELETE_FAILURE);
}
- return DP_REQUEST_SUCCESS;
+ return ZEBRA_DPLANE_REQUEST_SUCCESS;
}
int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla,
zif = (struct zebra_if *)ifp->info;
if ((br_if = zif->brslave_info.br_if) == NULL) {
- zlog_warn("%s family %s IF %s(%u) brIF %u - no bridge master",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
+ zlog_debug("%s family %s IF %s(%u) brIF %u - no bridge master",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
return 0;
}
netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len);
if (!tb[NDA_LLADDR]) {
- zlog_warn("%s family %s IF %s(%u) brIF %u - no LLADDR",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
+ zlog_debug("%s family %s IF %s(%u) brIF %u - no LLADDR",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
return 0;
}
if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) {
- zlog_warn(
+ zlog_debug(
"%s family %s IF %s(%u) brIF %u - LLADDR is not MAC, len %lu",
nl_msg_type_to_str(h->nlmsg_type),
nl_family_to_str(ndm->ndm_family), ifp->name,
zns = zvrf->zns;
zif = ifp->info;
if ((br_if = zif->brslave_info.br_if) == NULL) {
- zlog_warn("MAC %s on IF %s(%u) - no mapping to bridge",
- (cmd == RTM_NEWNEIGH) ? "add" : "del", ifp->name,
- ifp->ifindex);
+ zlog_debug("MAC %s on IF %s(%u) - no mapping to bridge",
+ (cmd == RTM_NEWNEIGH) ? "add" : "del", ifp->name,
+ ifp->ifindex);
return -1;
}
netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len);
if (!tb[NDA_DST]) {
- zlog_warn("%s family %s IF %s(%u) - no DST",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex);
+ zlog_debug("%s family %s IF %s(%u) - no DST",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex);
return 0;
}
/* Drop some "permanent" entries. */
if (ndm->ndm_state & NUD_PERMANENT) {
- char buf[16] = "169.254.0.1";
+ char b[16] = "169.254.0.1";
struct in_addr ipv4_ll;
if (ndm->ndm_family != AF_INET)
if (h->nlmsg_type != RTM_DELNEIGH)
return 0;
- inet_pton(AF_INET, buf, &ipv4_ll);
+ inet_pton(AF_INET, b, &ipv4_ll);
if (ipv4_ll.s_addr != ip.ip._v4_addr.s_addr)
return 0;
if (h->nlmsg_type == RTM_NEWNEIGH) {
if (tb[NDA_LLADDR]) {
if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) {
- zlog_warn(
+ zlog_debug(
"%s family %s IF %s(%u) - LLADDR is not MAC, len %lu",
nl_msg_type_to_str(h->nlmsg_type),
nl_family_to_str(ndm->ndm_family),
if (ndm->ndm_family == AF_INET || ndm->ndm_family == AF_INET6)
return netlink_ipneigh_change(h, len, ns_id);
else {
- zlog_warn(
- "Invalid address family: %u received from kernel neighbor change: %u",
- ndm->ndm_family, h->nlmsg_type);
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_FAMILY,
+ "Invalid address family: %u received from kernel neighbor change: %s",
+ ndm->ndm_family, nl_msg_type_to_str(h->nlmsg_type));
return 0;
}