diff options
Diffstat (limited to 'zebra/zapi_msg.c')
| -rw-r--r-- | zebra/zapi_msg.c | 119 |
1 files changed, 103 insertions, 16 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 571aaad9e1..0a459b4d0a 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -51,6 +51,7 @@ #include "zebra/zebra_mpls.h" #include "zebra/zebra_mroute.h" #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_evpn_mh.h" #include "zebra/rt.h" #include "zebra/zebra_pbr.h" #include "zebra/table_manager.h" @@ -729,9 +730,10 @@ static int route_notify_internal(const struct prefix *p, int type, char buff[PREFIX_STRLEN]; zlog_debug( - "Not Notifying Owner: %u about prefix %s(%u) %d vrf: %u", - type, prefix2str(p, buff, sizeof(buff)), - table_id, note, vrf_id); + "Not Notifying Owner: %s about prefix %s(%u) %d vrf: %u", + zebra_route_string(type), + prefix2str(p, buff, sizeof(buff)), table_id, + note, vrf_id); } return 0; } @@ -739,9 +741,10 @@ static int route_notify_internal(const struct prefix *p, int type, if (IS_ZEBRA_DEBUG_PACKET) { char buff[PREFIX_STRLEN]; - zlog_debug("Notifying Owner: %u about prefix %s(%u) %d vrf: %u", - type, prefix2str(p, buff, sizeof(buff)), - table_id, note, vrf_id); + zlog_debug("Notifying Owner: %s about prefix %s(%u) %d vrf: %u", + zebra_route_string(type), + prefix2str(p, buff, sizeof(buff)), table_id, note, + vrf_id); } s = stream_new(ZEBRA_MAX_PACKET_SIZ); @@ -1416,6 +1419,7 @@ static struct nexthop *nexthop_from_zapi(struct route_entry *re, struct nexthop *nexthop = NULL; struct ipaddr vtep_ip; struct interface *ifp; + int i; char nhbuf[INET6_ADDRSTRLEN] = ""; switch (api_nh->type) { @@ -1521,17 +1525,36 @@ static struct nexthop *nexthop_from_zapi(struct route_entry *re, nexthop->weight = api_nh->weight; if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) { - if (api_nh->backup_idx < api->backup_nexthop_num) { - /* Capture backup info */ - SET_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP); - nexthop->backup_idx = api_nh->backup_idx; - } else { - /* Warn about invalid backup index */ + /* Validate count */ + if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS) { if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s: invalid backup nh idx %d", - __func__, api_nh->backup_idx); + zlog_debug("%s: invalid backup nh count %d", + __func__, api_nh->backup_num); + nexthop_free(nexthop); + nexthop = NULL; + goto done; + } + + /* Copy backup info */ + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP); + nexthop->backup_num = api_nh->backup_num; + + for (i = 0; i < api_nh->backup_num; i++) { + /* Validate backup index */ + if (api_nh->backup_idx[i] < api->backup_nexthop_num) { + nexthop->backup_idx[i] = api_nh->backup_idx[i]; + } else { + if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s: invalid backup nh idx %d", + __func__, + api_nh->backup_idx[i]); + nexthop_free(nexthop); + nexthop = NULL; + goto done; + } } } + done: return nexthop; } @@ -1703,7 +1726,7 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) __func__, nhbuf); } UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP); - nexthop->backup_idx = 0; + nexthop->backup_num = 0; } /* MPLS labels for BGP-LU or Segment Routing */ @@ -1879,7 +1902,7 @@ static void zread_router_id_add(ZAPI_HANDLER_ARGS) /* Router-id information is needed. */ vrf_bitmap_set(client->ridinfo, zvrf_id(zvrf)); - router_id_get(&p, zvrf_id(zvrf)); + router_id_get(&p, zvrf); zsend_router_id_update(client, &p, zvrf_id(zvrf)); } @@ -1981,6 +2004,56 @@ static void zread_vrf_unregister(ZAPI_HANDLER_ARGS) } /* + * Validate incoming zapi mpls lsp / labels message + */ +static int zapi_labels_validate(const struct zapi_labels *zl) +{ + int ret = -1; + int i, j, idx; + uint32_t bits[8]; + uint32_t ival; + const struct zapi_nexthop *znh; + + /* Validate backup info: no duplicates for a single primary */ + if (zl->backup_nexthop_num == 0) { + ret = 0; + goto done; + } + + for (j = 0; j < zl->nexthop_num; j++) { + znh = &zl->nexthops[j]; + + memset(bits, 0, sizeof(bits)); + + for (i = 0; i < znh->backup_num; i++) { + idx = znh->backup_idx[i] / 32; + + ival = 1 << znh->backup_idx[i] % 32; + + /* Check whether value is already used */ + if (ival & bits[idx]) { + /* Fail */ + + if (IS_ZEBRA_DEBUG_RECV) + zlog_debug("%s: invalid zapi mpls message: duplicate backup nexthop index %d", + __func__, + znh->backup_idx[i]); + goto done; + } + + /* Mark index value */ + bits[idx] |= ival; + } + } + + ret = 0; + +done: + + return ret; +} + +/* * Handle request to create an MPLS LSP. * * A single message can fully specify an LSP with multiple nexthops. @@ -2006,6 +2079,10 @@ static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS) if (!mpls_enabled) return; + /* Validate; will debug on failure */ + if (zapi_labels_validate(&zl) < 0) + return; + ret = mpls_zapi_labels_process(true, zvrf, &zl); if (ret < 0) { if (IS_ZEBRA_DEBUG_RECV) @@ -2087,6 +2164,10 @@ static void zread_mpls_labels_replace(ZAPI_HANDLER_ARGS) if (!mpls_enabled) return; + /* Validate; will debug on failure */ + if (zapi_labels_validate(&zl) < 0) + return; + /* This removes everything, then re-adds from the client's * zapi message. Since the LSP will be processed later, on this * this same pthread, all of the changes will 'appear' at once. @@ -2526,6 +2607,7 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS) STREAM_GET(&zpr.rule.filter.dst_ip.u.prefix, s, prefix_blen(&zpr.rule.filter.dst_ip)); STREAM_GETW(s, zpr.rule.filter.dst_port); + STREAM_GETC(s, zpr.rule.filter.dsfield); STREAM_GETL(s, zpr.rule.filter.fwmark); STREAM_GETL(s, zpr.rule.action.table); STREAM_GETL(s, zpr.rule.ifindex); @@ -2556,6 +2638,9 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS) if (zpr.rule.filter.dst_port) zpr.rule.filter.filter_bm |= PBR_FILTER_DST_PORT; + if (zpr.rule.filter.dsfield) + zpr.rule.filter.filter_bm |= PBR_FILTER_DSFIELD; + if (zpr.rule.filter.fwmark) zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK; @@ -2808,6 +2893,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_ADVERTISE_SVI_MACIP] = zebra_vxlan_advertise_svi_macip, [ZEBRA_ADVERTISE_SUBNET] = zebra_vxlan_advertise_subnet, [ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni, + [ZEBRA_REMOTE_ES_VTEP_ADD] = zebra_evpn_proc_remote_es, + [ZEBRA_REMOTE_ES_VTEP_DEL] = zebra_evpn_proc_remote_es, [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add, [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del, [ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add, |
