diff options
| -rw-r--r-- | zebra/if_netlink.c | 6 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 240 |
2 files changed, 112 insertions, 134 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 843e2b3734..a29a810902 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -903,8 +903,8 @@ int kernel_interface_set_master(struct interface *master, req.ifa.ifi_index = slave->ifindex; - nl_attr_put(&req.n, sizeof(req), IFLA_MASTER, &master->ifindex, 4); - nl_attr_put(&req.n, sizeof(req), IFLA_LINK, &slave->ifindex, 4); + nl_attr_put32(&req.n, sizeof(req), IFLA_MASTER, master->ifindex); + nl_attr_put32(&req.n, sizeof(req), IFLA_LINK, slave->ifindex); return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); @@ -1521,7 +1521,7 @@ int netlink_protodown(struct interface *ifp, bool down) req.ifa.ifi_index = ifp->ifindex; nl_attr_put(&req.n, sizeof(req), IFLA_PROTO_DOWN, &down, sizeof(down)); - nl_attr_put(&req.n, sizeof(req), IFLA_LINK, &ifp->ifindex, 4); + nl_attr_put32(&req.n, sizeof(req), IFLA_LINK, ifp->ifindex); return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 9261d1b975..db574e748b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1095,37 +1095,14 @@ static int build_label_stack(struct mpls_label_stack *nh_label, return num_labels; } -/* This function takes a nexthop as argument and adds - * the appropriate netlink attributes to an existing - * netlink message. - * - * @param routedesc: Human readable description of route type - * (direct/recursive, single-/multipath) - * @param bytelen: Length of addresses in bytes. - * @param nexthop: Nexthop information - * @param nlmsg: nlmsghdr structure to fill in. - * @param req_size: The size allocated for the message. - * - * The function returns true if the nexthop could be added - * to the message, otherwise false is returned. - */ -static bool _netlink_route_build_singlepath(const struct prefix *p, - const char *routedesc, int bytelen, - const struct nexthop *nexthop, - struct nlmsghdr *nlmsg, - struct rtmsg *rtmsg, - size_t req_size, int cmd) +static bool _netlink_route_encode_label_info(struct mpls_label_stack *nh_label, + struct nlmsghdr *nlmsg, + size_t buflen, struct rtmsg *rtmsg, + char *label_buf, + size_t label_buf_size) { - mpls_lse_t out_lse[MPLS_MAX_LABELS]; - char label_buf[256]; - int num_labels = 0; - struct vrf *vrf; - char addrstr[INET6_ADDRSTRLEN]; - - assert(nexthop); - - vrf = vrf_lookup_by_id(nexthop->vrf_id); + int num_labels; /* * label_buf is *only* currently used within debugging. @@ -1135,30 +1112,29 @@ static bool _netlink_route_build_singlepath(const struct prefix *p, */ label_buf[0] = '\0'; - num_labels = build_label_stack(nexthop->nh_label, out_lse, label_buf, - sizeof(label_buf)); + num_labels = + build_label_stack(nh_label, out_lse, label_buf, label_buf_size); if (num_labels) { /* Set the BoS bit */ out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT); if (rtmsg->rtm_family == AF_MPLS) { - if (!nl_attr_put(nlmsg, req_size, RTA_NEWDST, &out_lse, + if (!nl_attr_put(nlmsg, buflen, RTA_NEWDST, &out_lse, num_labels * sizeof(mpls_lse_t))) return false; } else { struct rtattr *nest; - uint16_t encap = LWTUNNEL_ENCAP_MPLS; - if (!nl_attr_put(nlmsg, req_size, RTA_ENCAP_TYPE, - &encap, sizeof(uint16_t))) + if (!nl_attr_put16(nlmsg, buflen, RTA_ENCAP_TYPE, + LWTUNNEL_ENCAP_MPLS)) return false; - nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP); + nest = nl_attr_nest(nlmsg, buflen, RTA_ENCAP); if (!nest) return false; - if (!nl_attr_put(nlmsg, req_size, MPLS_IPTUNNEL_DST, + if (!nl_attr_put(nlmsg, buflen, MPLS_IPTUNNEL_DST, &out_lse, num_labels * sizeof(mpls_lse_t))) return false; @@ -1166,6 +1142,74 @@ static bool _netlink_route_build_singlepath(const struct prefix *p, } } + return true; +} + +static bool _netlink_route_encode_nexthop_src(const struct nexthop *nexthop, + int family, + struct nlmsghdr *nlmsg, + size_t buflen, int bytelen) +{ + if (family == AF_INET) { + if (nexthop->rmap_src.ipv4.s_addr != INADDR_ANY) { + if (!nl_attr_put(nlmsg, buflen, RTA_PREFSRC, + &nexthop->rmap_src.ipv4, bytelen)) + return false; + } else if (nexthop->src.ipv4.s_addr != INADDR_ANY) { + if (!nl_attr_put(nlmsg, buflen, RTA_PREFSRC, + &nexthop->src.ipv4, bytelen)) + return false; + } + } else if (family == AF_INET6) { + if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) { + if (!nl_attr_put(nlmsg, buflen, RTA_PREFSRC, + &nexthop->rmap_src.ipv6, bytelen)) + return false; + } else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) { + if (!nl_attr_put(nlmsg, buflen, RTA_PREFSRC, + &nexthop->src.ipv6, bytelen)) + return false; + } + } + + return true; +} + +/* This function takes a nexthop as argument and adds + * the appropriate netlink attributes to an existing + * netlink message. + * + * @param routedesc: Human readable description of route type + * (direct/recursive, single-/multipath) + * @param bytelen: Length of addresses in bytes. + * @param nexthop: Nexthop information + * @param nlmsg: nlmsghdr structure to fill in. + * @param req_size: The size allocated for the message. + * + * The function returns true if the nexthop could be added + * to the message, otherwise false is returned. + */ +static bool _netlink_route_build_singlepath(const struct prefix *p, + const char *routedesc, int bytelen, + const struct nexthop *nexthop, + struct nlmsghdr *nlmsg, + struct rtmsg *rtmsg, + size_t req_size, int cmd) +{ + + char label_buf[256]; + struct vrf *vrf; + char addrstr[INET6_ADDRSTRLEN]; + + assert(nexthop); + + vrf = vrf_lookup_by_id(nexthop->vrf_id); + + if (!_netlink_route_encode_label_info(nexthop->nh_label, nlmsg, + req_size, rtmsg, label_buf, + sizeof(label_buf))) + return false; + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) rtmsg->rtm_flags |= RTNH_F_ONLINK; @@ -1176,15 +1220,9 @@ static bool _netlink_route_build_singlepath(const struct prefix *p, if (!nl_attr_put32(nlmsg, req_size, RTA_OIF, nexthop->ifindex)) return false; - if (nexthop->rmap_src.ipv4.s_addr != INADDR_ANY - && (cmd == RTM_NEWROUTE)) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->rmap_src.ipv4, bytelen)) - return false; - } else if (nexthop->src.ipv4.s_addr != INADDR_ANY - && (cmd == RTM_NEWROUTE)) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->src.ipv4, bytelen)) + if (cmd == RTM_NEWROUTE) { + if (!_netlink_route_encode_nexthop_src( + nexthop, AF_INET, nlmsg, req_size, bytelen)) return false; } @@ -1207,16 +1245,9 @@ static bool _netlink_route_build_singlepath(const struct prefix *p, } if (cmd == RTM_NEWROUTE) { - if (nexthop->rmap_src.ipv4.s_addr != INADDR_ANY) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->rmap_src.ipv4, - bytelen)) - return false; - } else if (nexthop->src.ipv4.s_addr != INADDR_ANY) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->src.ipv4, bytelen)) - return false; - } + if (!_netlink_route_encode_nexthop_src( + nexthop, AF_INET, nlmsg, req_size, bytelen)) + return false; } if (IS_ZEBRA_DEBUG_KERNEL) { @@ -1237,17 +1268,10 @@ static bool _netlink_route_build_singlepath(const struct prefix *p, return false; if (cmd == RTM_NEWROUTE) { - if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->rmap_src.ipv6, - bytelen)) - return false; - } else if (!IN6_IS_ADDR_UNSPECIFIED( - &nexthop->src.ipv6)) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->src.ipv6, bytelen)) - return false; - } + if (!_netlink_route_encode_nexthop_src( + nexthop, AF_INET6, nlmsg, req_size, + bytelen)) + return false; } if (IS_ZEBRA_DEBUG_KERNEL) { @@ -1272,16 +1296,9 @@ static bool _netlink_route_build_singlepath(const struct prefix *p, if (nexthop->type == NEXTHOP_TYPE_IFINDEX) { if (cmd == RTM_NEWROUTE) { - if (nexthop->rmap_src.ipv4.s_addr != INADDR_ANY) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->rmap_src.ipv4, - bytelen)) - return false; - } else if (nexthop->src.ipv4.s_addr != INADDR_ANY) { - if (!nl_attr_put(nlmsg, req_size, RTA_PREFSRC, - &nexthop->src.ipv4, bytelen)) - return false; - } + if (!_netlink_route_encode_nexthop_src( + nexthop, AF_INET, nlmsg, req_size, bytelen)) + return false; } if (IS_ZEBRA_DEBUG_KERNEL) @@ -1318,9 +1335,7 @@ static bool _netlink_route_build_multipath(const struct prefix *p, size_t req_size, struct rtmsg *rtmsg, const union g_addr **src) { - mpls_lse_t out_lse[MPLS_MAX_LABELS]; char label_buf[256]; - int num_labels = 0; struct vrf *vrf; struct rtnexthop *rtnh; @@ -1332,53 +1347,17 @@ static bool _netlink_route_build_multipath(const struct prefix *p, vrf = vrf_lookup_by_id(nexthop->vrf_id); - /* - * label_buf is *only* currently used within debugging. - * As such when we assign it we are guarding it inside - * a debug test. If you want to change this make sure - * you fix this assumption - */ - label_buf[0] = '\0'; - - num_labels = build_label_stack(nexthop->nh_label, out_lse, label_buf, - sizeof(label_buf)); - - if (num_labels) { - /* Set the BoS bit */ - out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT); - - if (rtmsg->rtm_family == AF_MPLS) { - if (!nl_attr_put(nlmsg, req_size, RTA_NEWDST, &out_lse, - num_labels * sizeof(mpls_lse_t))) - return false; - } else { - struct rtattr *nest; - uint16_t encap = LWTUNNEL_ENCAP_MPLS; - - if (!nl_attr_put(nlmsg, req_size, RTA_ENCAP_TYPE, - &encap, sizeof(uint16_t))) - return false; - - nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP); - if (nest == NULL) - return false; - - if (!nl_attr_put(nlmsg, req_size, MPLS_IPTUNNEL_DST, - &out_lse, - num_labels * sizeof(mpls_lse_t))) - return false; - nl_attr_nest_end(nlmsg, nest); - } - } + if (!_netlink_route_encode_label_info(nexthop->nh_label, nlmsg, + req_size, rtmsg, label_buf, + sizeof(label_buf))) + return false; if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) rtnh->rtnh_flags |= RTNH_F_ONLINK; if (is_route_v4_over_v6(rtmsg->rtm_family, nexthop->type)) { - bytelen = 4; rtnh->rtnh_flags |= RTNH_F_ONLINK; - if (!nl_attr_put(nlmsg, req_size, RTA_GATEWAY, &ipv4_ll, - bytelen)) + if (!nl_attr_put(nlmsg, req_size, RTA_GATEWAY, &ipv4_ll, 4)) return false; rtnh->rtnh_ifindex = nexthop->ifindex; if (nexthop->weight) @@ -1531,7 +1510,7 @@ static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla, nl_attr_put(&req.n, sizeof(req), NDA_PROTOCOL, &protocol, sizeof(protocol)); - nl_attr_put(&req.n, sizeof(req), NDA_DST, &addr, 4); + nl_attr_put32(&req.n, sizeof(req), NDA_DST, addr); nl_attr_put(&req.n, sizeof(req), NDA_LLADDR, lla, llalen); return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, @@ -1573,8 +1552,7 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, switch (nh->nh_encap_type) { case NET_VXLAN: - if (!nl_attr_put(n, nlen, RTA_ENCAP_TYPE, &nh->nh_encap_type, - sizeof(uint16_t))) + if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type)) return false; nest = nl_attr_nest(n, nlen, RTA_ENCAP); @@ -1962,10 +1940,10 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in) req.ndm.ndm_family = RTNL_FAMILY_IPMR; req.n.nlmsg_type = RTM_GETROUTE; - nl_attr_put(&req.n, sizeof(req), RTA_IIF, &mroute->ifindex, 4); - nl_attr_put(&req.n, sizeof(req), RTA_OIF, &mroute->ifindex, 4); - nl_attr_put(&req.n, sizeof(req), RTA_SRC, &mroute->sg.src.s_addr, 4); - nl_attr_put(&req.n, sizeof(req), RTA_DST, &mroute->sg.grp.s_addr, 4); + nl_attr_put32(&req.n, sizeof(req), RTA_IIF, mroute->ifindex); + nl_attr_put32(&req.n, sizeof(req), RTA_OIF, mroute->ifindex); + nl_attr_put32(&req.n, sizeof(req), RTA_SRC, mroute->sg.src.s_addr); + nl_attr_put32(&req.n, sizeof(req), RTA_DST, mroute->sg.grp.s_addr); /* * What? * @@ -1982,7 +1960,7 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in) */ actual_table = (zvrf->table_id == RT_TABLE_MAIN) ? RT_TABLE_DEFAULT : zvrf->table_id; - nl_attr_put(&req.n, sizeof(req), RTA_TABLE, &actual_table, 4); + nl_attr_put32(&req.n, sizeof(req), RTA_TABLE, actual_table); suc = netlink_talk(netlink_route_change_read_multicast, &req.n, &zns->netlink_cmd, zns, 0); @@ -2180,9 +2158,9 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, struct rtattr *nest; uint16_t encap = LWTUNNEL_ENCAP_MPLS; - if (!nl_attr_put(&req->n, buflen, - NHA_ENCAP_TYPE, &encap, - sizeof(uint16_t))) + if (!nl_attr_put16(&req->n, buflen, + NHA_ENCAP_TYPE, + encap)) return 0; nest = nl_attr_nest(&req->n, buflen, NHA_ENCAP); |
