X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=bgpd%2Fbgp_zebra.c;h=d201b48bad7d77f105d4e2ff6d3885dfbae16f7c;hb=2da7d62e94997683e141e4b1d092eaedff16d3fb;hp=4a909d8cdc0247b5c0bb94fcc1b0eb4c248a5f4b;hpb=51f9d3e70ffa6e27fdb51ecc10b618091d518c28;p=mirror_frr.git diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 4a909d8cd..d201b48ba 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1001,6 +1001,7 @@ static bool bgp_tm_status_connected; static bool bgp_tm_chunk_obtained; #define BGP_FLOWSPEC_TABLE_CHUNK 100000 static uint32_t bgp_tm_min, bgp_tm_max, bgp_tm_chunk_size; +struct bgp *bgp_tm_bgp; static int bgp_zebra_tm_connect(struct thread *t) { @@ -1024,8 +1025,11 @@ static int bgp_zebra_tm_connect(struct thread *t) if (!bgp_tm_chunk_obtained) { if (bgp_zebra_get_table_range(bgp_tm_chunk_size, &bgp_tm_min, - &bgp_tm_max) >= 0) + &bgp_tm_max) >= 0) { bgp_tm_chunk_obtained = true; + /* parse non installed entries */ + bgp_zebra_announce_table(bgp_tm_bgp, AFI_IP, SAFI_FLOWSPEC); + } } } thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay, @@ -1033,6 +1037,11 @@ static int bgp_zebra_tm_connect(struct thread *t) return 0; } +bool bgp_zebra_tm_chunk_obtained(void) +{ + return bgp_tm_chunk_obtained; +} + uint32_t bgp_zebra_tm_get_id(void) { static int table_id; @@ -1042,7 +1051,7 @@ uint32_t bgp_zebra_tm_get_id(void) return bgp_tm_min++; } -void bgp_zebra_init_tm_connect(void) +void bgp_zebra_init_tm_connect(struct bgp *bgp) { int delay = 1; @@ -1054,6 +1063,7 @@ void bgp_zebra_init_tm_connect(void) bgp_tm_chunk_obtained = false; bgp_tm_min = bgp_tm_max = 0; bgp_tm_chunk_size = BGP_FLOWSPEC_TABLE_CHUNK; + bgp_tm_bgp = bgp; thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay, &bgp_tm_thread_connect); } @@ -1193,7 +1203,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, return; if (bgp_debug_zebra(p)) - prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix)); + prefix2str(p, buf_prefix, sizeof(buf_prefix)); if (safi == SAFI_FLOWSPEC) return bgp_pbr_update_entry(bgp, &rn->p, @@ -1225,13 +1235,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, tag = info->attr->tag; - /* - * When we create an aggregate route we must also install a - * Null0 route in the RIB - */ - if (info->sub_type == BGP_ROUTE_AGGREGATE) - zapi_route_set_blackhole(&api, BLACKHOLE_NULL); - /* If the route's source is EVPN, flag as such. */ is_evpn = is_route_parent_evpn(info); if (is_evpn) @@ -1313,7 +1316,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, &mpinfo_cp->attr->nexthop, mpinfo_cp->attr, is_evpn, api_nh); } else { - ifindex_t ifindex; + ifindex_t ifindex = IFINDEX_INTERNAL; struct in6_addr *nexthop; if (bgp->table_map[afi][safi].name) { @@ -1371,7 +1374,14 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, if (has_valid_label && !(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))) SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); - if (info->sub_type != BGP_ROUTE_AGGREGATE) + /* + * When we create an aggregate route we must also + * install a Null0 route in the RIB, so overwrite + * what was written into api with a blackhole route + */ + if (info->sub_type == BGP_ROUTE_AGGREGATE) + zapi_route_set_blackhole(&api, BLACKHOLE_NULL); + else api.nexthop_num = valid_nh_count; SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); @@ -1962,6 +1972,7 @@ static int rule_notify_owner(int command, struct zclient *zclient, zlog_debug("%s: Received RULE_INSTALLED", __PRETTY_FUNCTION__); break; + case ZAPI_RULE_FAIL_REMOVE: case ZAPI_RULE_REMOVED: if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: Received RULE REMOVED", @@ -1987,8 +1998,8 @@ static int ipset_notify_owner(int command, struct zclient *zclient, bgp_pbim = bgp_pbr_match_ipset_lookup(vrf_id, unique); if (!bgp_pbim) { if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("%s: Fail to look BGP match (%u)", - __PRETTY_FUNCTION__, unique); + zlog_debug("%s: Fail to look BGP match ( %u %u)", + __PRETTY_FUNCTION__, note, unique); return 0; } @@ -2007,6 +2018,7 @@ static int ipset_notify_owner(int command, struct zclient *zclient, zlog_debug("%s: Received IPSET_INSTALLED", __PRETTY_FUNCTION__); break; + case ZAPI_IPSET_FAIL_REMOVE: case ZAPI_IPSET_REMOVED: if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: Received IPSET REMOVED", @@ -2036,8 +2048,8 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient, unique); if (!bgp_pbime) { if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("%s: Fail to look BGP match entry (%u)", - __PRETTY_FUNCTION__, unique); + zlog_debug("%s: Fail to look BGP match entry (%u %u)", + __PRETTY_FUNCTION__, note, unique); return 0; } @@ -2050,12 +2062,22 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient, bgp_pbime->install_in_progress = false; break; case ZAPI_IPSET_ENTRY_INSTALLED: - bgp_pbime->installed = true; - bgp_pbime->install_in_progress = false; - if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("%s: Received IPSET_ENTRY_INSTALLED", - __PRETTY_FUNCTION__); + { + struct bgp_info *bgp_info; + struct bgp_info_extra *extra; + + bgp_pbime->installed = true; + bgp_pbime->install_in_progress = false; + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: Received IPSET_ENTRY_INSTALLED", + __PRETTY_FUNCTION__); + /* link bgp_info to bpme */ + bgp_info = (struct bgp_info *)bgp_pbime->bgp_info; + extra = bgp_info_extra_get(bgp_info); + extra->bgp_fs_pbr = (void *)bgp_pbime; + } break; + case ZAPI_IPSET_ENTRY_FAIL_REMOVE: case ZAPI_IPSET_ENTRY_REMOVED: if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: Received IPSET_ENTRY_REMOVED", @@ -2080,8 +2102,8 @@ static int iptable_notify_owner(int command, struct zclient *zclient, bgpm = bgp_pbr_match_iptable_lookup(vrf_id, unique); if (!bgpm) { if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("%s: Fail to look BGP iptable (%u)", - __PRETTY_FUNCTION__, unique); + zlog_debug("%s: Fail to look BGP iptable (%u %u)", + __PRETTY_FUNCTION__, note, unique); return 0; } switch (note) { @@ -2100,6 +2122,7 @@ static int iptable_notify_owner(int command, struct zclient *zclient, __PRETTY_FUNCTION__); bgpm->action->refcnt++; break; + case ZAPI_IPTABLE_FAIL_REMOVE: case ZAPI_IPTABLE_REMOVED: if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("%s: Received IPTABLE REMOVED", @@ -2167,6 +2190,12 @@ static void bgp_encode_pbr_ipset_entry_match(struct stream *s, stream_putc(s, pbime->dst.family); stream_putc(s, pbime->dst.prefixlen); stream_put(s, &pbime->dst.u.prefix, prefix_blen(&pbime->dst)); + + stream_putw(s, pbime->src_port_min); + stream_putw(s, pbime->src_port_max); + stream_putw(s, pbime->dst_port_min); + stream_putw(s, pbime->dst_port_max); + stream_putc(s, pbime->proto); } static void bgp_encode_pbr_iptable_match(struct stream *s, @@ -2190,6 +2219,10 @@ static void bgp_encode_pbr_iptable_match(struct stream *s, stream_putl(s, bpa->fwmark); stream_put(s, pbm->ipset_name, ZEBRA_IPSET_NAME_SIZE); + stream_putw(s, pbm->pkt_len_min); + stream_putw(s, pbm->pkt_len_max); + stream_putw(s, pbm->tcp_flags); + stream_putw(s, pbm->tcp_mask_flags); } /* BGP has established connection with Zebra. */ @@ -2220,6 +2253,40 @@ static void bgp_zebra_connected(struct zclient *zclient) */ } +static int bgp_zebra_process_local_es(int cmd, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) +{ + esi_t esi; + struct bgp *bgp = NULL; + struct stream *s = NULL; + char buf[ESI_STR_LEN]; + char buf1[INET6_ADDRSTRLEN]; + struct ipaddr originator_ip; + + memset(&esi, 0, sizeof(esi_t)); + memset(&originator_ip, 0, sizeof(struct ipaddr)); + + bgp = bgp_lookup_by_vrf_id(vrf_id); + if (!bgp) + return 0; + + s = zclient->ibuf; + stream_get(&esi, s, sizeof(esi_t)); + stream_get(&originator_ip, s, sizeof(struct ipaddr)); + + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Rx %s ESI %s originator-ip %s", + (cmd == ZEBRA_LOCAL_ES_ADD) ? "add" : "del", + esi_to_str(&esi, buf, sizeof(buf)), + ipaddr2str(&originator_ip, buf1, sizeof(buf1))); + + if (cmd == ZEBRA_LOCAL_ES_ADD) + bgp_evpn_local_es_add(bgp, &esi, &originator_ip); + else + bgp_evpn_local_es_del(bgp, &esi, &originator_ip); + return 0; +} + static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { @@ -2455,6 +2522,8 @@ void bgp_zebra_init(struct thread_master *master) zclient->nexthop_update = bgp_read_nexthop_update; zclient->import_check_update = bgp_read_import_check_update; zclient->fec_update = bgp_read_fec_update; + zclient->local_es_add = bgp_zebra_process_local_es; + zclient->local_es_del = bgp_zebra_process_local_es; zclient->local_vni_add = bgp_zebra_process_local_vni; zclient->local_vni_del = bgp_zebra_process_local_vni; zclient->local_macip_add = bgp_zebra_process_local_macip; @@ -2490,8 +2559,10 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra, bool install) if (pbra->install_in_progress) return; - zlog_debug("%s: table %d fwmark %d %d", __PRETTY_FUNCTION__, - pbra->table_id, pbra->fwmark, install); + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: table %d fwmark %d %d", + __PRETTY_FUNCTION__, + pbra->table_id, pbra->fwmark, install); s = zclient->obuf; stream_reset(s); @@ -2513,8 +2584,10 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install) if (pbrim->install_in_progress) return; - zlog_debug("%s: name %s type %d %d", __PRETTY_FUNCTION__, - pbrim->ipset_name, pbrim->type, install); + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: name %s type %d %d", + __PRETTY_FUNCTION__, + pbrim->ipset_name, pbrim->type, install); s = zclient->obuf; stream_reset(s); @@ -2539,9 +2612,10 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime, if (pbrime->install_in_progress) return; - zlog_debug("%s: name %s %d %d", __PRETTY_FUNCTION__, - pbrime->backpointer->ipset_name, - pbrime->unique, install); + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: name %s %d %d", __PRETTY_FUNCTION__, + pbrime->backpointer->ipset_name, + pbrime->unique, install); s = zclient->obuf; stream_reset(s); @@ -2559,16 +2633,56 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime, pbrime->install_in_progress = true; } +static void bgp_encode_pbr_interface_list(struct bgp *bgp, struct stream *s) +{ + struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg; + struct bgp_pbr_interface_head *head; + struct bgp_pbr_interface *pbr_if; + struct interface *ifp; + + if (!bgp_pbr_cfg) + return; + head = &(bgp_pbr_cfg->ifaces_by_name_ipv4); + + RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) { + ifp = if_lookup_by_name(pbr_if->name, bgp->vrf_id); + if (ifp) + stream_putl(s, ifp->ifindex); + } +} + +static int bgp_pbr_get_ifnumber(struct bgp *bgp) +{ + struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg; + struct bgp_pbr_interface_head *head; + struct bgp_pbr_interface *pbr_if; + int cnt = 0; + + if (!bgp_pbr_cfg) + return 0; + head = &(bgp_pbr_cfg->ifaces_by_name_ipv4); + + RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) { + if (if_lookup_by_name(pbr_if->name, bgp->vrf_id)) + cnt++; + } + return cnt; +} + void bgp_send_pbr_iptable(struct bgp_pbr_action *pba, struct bgp_pbr_match *pbm, bool install) { struct stream *s; + int ret = 0; + int nb_interface; if (pbm->install_iptable_in_progress) return; - zlog_debug("%s: name %s type %d mark %d %d", __PRETTY_FUNCTION__, - pbm->ipset_name, pbm->type, pba->fwmark, install); + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s: name %s type %d mark %d %d", + __PRETTY_FUNCTION__, pbm->ipset_name, + pbm->type, pba->fwmark, install); s = zclient->obuf; stream_reset(s); @@ -2578,11 +2692,17 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba, VRF_DEFAULT); bgp_encode_pbr_iptable_match(s, pba, pbm); - + nb_interface = bgp_pbr_get_ifnumber(pba->bgp); + stream_putl(s, nb_interface); + if (nb_interface) + bgp_encode_pbr_interface_list(pba->bgp, s); stream_putw_at(s, 0, stream_get_endp(s)); - if (!zclient_send_message(zclient) && install) { - pbm->install_iptable_in_progress = true; - pba->refcnt++; + ret = zclient_send_message(zclient); + if (install) { + if (ret) + pba->refcnt++; + else + pbm->install_iptable_in_progress = true; } } @@ -2626,7 +2746,8 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh, inet_ntop(AF_INET, &(nh->gate.ipv4), buff, INET_ADDRSTRLEN); if (BGP_DEBUG(zebra, ZEBRA)) - zlog_info("BGP: sending default route to %s table %d (redirect IP)", + zlog_info("BGP: %s default route to %s table %d (redirect IP)", + announce ? "adding" : "withdrawing", buff, table_id); zclient_route_send(announce ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, @@ -2648,7 +2769,8 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh, api_nh->type = NEXTHOP_TYPE_IFINDEX; api_nh->ifindex = ifp->ifindex; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_info("BGP: sending default route to %s table %d (redirect VRF)", + zlog_info("BGP: %s default route to %s table %d (redirect VRF)", + announce ? "adding" : "withdrawing", vrf->name, table_id); zclient_route_send(announce ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,