X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=zebra%2Frt_netlink.c;h=a77814668d4518d179abf30db4d5ea2b3081678d;hb=7726c479644269fc573dd6aad72ea9c163599fd6;hp=e8333ef0cf645fbb32bc43aeae0872e099ba1911;hpb=453a5340a8dc1400f44d1843b8687ac750282b12;p=mirror_frr.git diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index e8333ef0c..a77814668 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -98,7 +98,7 @@ static inline int is_selfroute(int proto) || (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG) || (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP) || (proto == RTPROT_LDP) || (proto == RTPROT_BABEL) - || (proto == RTPROT_RIP)) { + || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP)) { return 1; } @@ -139,6 +139,9 @@ static inline int zebra2proto(int proto) case ZEBRA_ROUTE_LDP: proto = RTPROT_LDP; break; + case ZEBRA_ROUTE_SHARP: + proto = RTPROT_SHARP; + break; default: proto = RTPROT_ZEBRA; break; @@ -227,6 +230,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, int metric = 0; u_int32_t mtu = 0; uint8_t distance = 0; + route_tag_t tag = 0; void *dest = NULL; void *gate = NULL; @@ -318,6 +322,11 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (tb[RTA_PRIORITY]) metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]); +#if defined(SUPPORT_REALMS) + if (tb[RTA_FLOW]) + tag = *(uint32_t *)RTA_DATA(tb[RTA_FLOW]); +#endif + if (tb[RTA_METRICS]) { struct rtattr *mxrta[RTAX_MAX + 1]; @@ -426,7 +435,8 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, memcpy(&nh.gate, gate, sz); rib_add(afi, SAFI_UNICAST, vrf_id, proto, - 0, flags, &p, NULL, &nh, table, metric, mtu, distance); + 0, flags, &p, NULL, &nh, table, metric, + mtu, distance, tag); } else { /* This is a multipath route */ @@ -446,6 +456,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, re->table = table; re->nexthop_num = 0; re->uptime = time(NULL); + re->tag = tag; for (;;) { if (len < (int)sizeof(*rtnh) @@ -532,13 +543,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, memcpy(&nh.gate, gate, sz); rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, NULL, &nh, - table, metric, true); + table, metric, true, NULL); } else { /* XXX: need to compare the entire list of nexthops * here for NLM_F_APPEND stupidity */ rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, NULL, NULL, - table, metric, true); + table, metric, true, NULL); } } @@ -1307,7 +1318,10 @@ static int netlink_route_multipath(int cmd, struct prefix *p, * by the routing protocol and for communicating with protocol peers. */ addattr32(&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC); - +#if defined(SUPPORT_REALMS) + if (re->tag > 0 && re->tag <= 255) + addattr32(&req.n, sizeof req, RTA_FLOW, re->tag); +#endif /* Table corresponding to this route. */ if (re->table < 256) req.r.rtm_table = re->table; @@ -1595,17 +1609,51 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in) return suc; } -int kernel_route_rib(struct prefix *p, struct prefix *src_p, - struct route_entry *old, struct route_entry *new) +void kernel_route_rib(struct prefix *p, struct prefix *src_p, + struct route_entry *old, struct route_entry *new) { + int ret = 0; + assert(old || new); - if (!old && new) - return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 0); - if (old && !new) - return netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0); + if (new) { + if (p->family == AF_INET) + ret = netlink_route_multipath(RTM_NEWROUTE, p, src_p, + new, (old) ? 1 : 0); + else { + /* + * So v6 route replace semantics are not in + * the kernel at this point as I understand it. + * So let's do a delete than an add. + * In the future once v6 route replace semantics + * are in we can figure out what to do here to + * allow working with old and new kernels. + * + * I'm also intentionally ignoring the failure case + * of the route delete. If that happens yeah we're + * screwed. + */ + if (old) + netlink_route_multipath(RTM_DELROUTE, p, + src_p, old, 0); + ret = netlink_route_multipath(RTM_NEWROUTE, p, + src_p, new, 0); + } + kernel_route_rib_pass_fail(p, new, + (!ret) ? + SOUTHBOUND_INSTALL_SUCCESS : + SOUTHBOUND_INSTALL_FAILURE); + return; + } + + if (old) { + ret = netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0); - return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 1); + kernel_route_rib_pass_fail(p, old, + (!ret) ? + SOUTHBOUND_DELETE_SUCCESS : + SOUTHBOUND_DELETE_FAILURE); + } } int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla, @@ -2395,17 +2443,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp) _netlink_mpls_build_singlepath(routedesc, nhlfe, &req.n, &req.r, sizeof req, cmd); - if (cmd == RTM_NEWROUTE) { - SET_FLAG(nhlfe->flags, - NHLFE_FLAG_INSTALLED); - SET_FLAG(nexthop->flags, - NEXTHOP_FLAG_FIB); - } else { - UNSET_FLAG(nhlfe->flags, - NHLFE_FLAG_INSTALLED); - UNSET_FLAG(nexthop->flags, - NEXTHOP_FLAG_FIB); - } nexthop_num++; break; } @@ -2449,18 +2486,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp) rta, rtnh, &req.r, &src1); rtnh = RTNH_NEXT(rtnh); - - if (cmd == RTM_NEWROUTE) { - SET_FLAG(nhlfe->flags, - NHLFE_FLAG_INSTALLED); - SET_FLAG(nexthop->flags, - NEXTHOP_FLAG_FIB); - } else { - UNSET_FLAG(nhlfe->flags, - NHLFE_FLAG_INSTALLED); - UNSET_FLAG(nexthop->flags, - NEXTHOP_FLAG_FIB); - } } }