From 28864ce1b054019629b4bfc3a67ec98169ad7af9 Mon Sep 17 00:00:00 2001 From: Yue Gao Date: Thu, 12 Dec 2024 10:07:29 -0800 Subject: [PATCH 1/2] Enable ipv6 on data ports - ipv6 link local addess is enabled by default in SONIC - Remove manifest.json, which is generated from build - correct indentation in SaiVppXlate.c --- docker-syncd-vpp/manifest.json | 39 -- saivpp/src/SwitchStateBaseHostif.cpp | 10 + saivpp/src/vppxlate/SaiVppXlate.c | 571 +++++++++++++++------------ saivpp/src/vppxlate/SaiVppXlate.h | 1 + 4 files changed, 320 insertions(+), 301 deletions(-) delete mode 100644 docker-syncd-vpp/manifest.json diff --git a/docker-syncd-vpp/manifest.json b/docker-syncd-vpp/manifest.json deleted file mode 100644 index 87f8c3cf..00000000 --- a/docker-syncd-vpp/manifest.json +++ /dev/null @@ -1,39 +0,0 @@ - -{ - "version": "1.0.0", - "package": { - "version": "1.0.0+dbg", - "depends": [], - "name": "syncd" - }, - "service": { - "name": "syncd", - "requires": [], - "after": [], - "before": [], - "dependent-of": [], - "asic-service": true, - "host-service": false, - "warm-shutdown": { - "after": [], - "before": [] - }, - "fast-shutdown": { - "after": [], - "before": [] - }, - "syslog": { - "support-rate-limit": true - } - }, - "container": { - "privileged": false, - "volumes": [], - "tmpfs": [] - }, - "cli": { - "config": "", - "show": "", - "clear": "" - } -} diff --git a/saivpp/src/SwitchStateBaseHostif.cpp b/saivpp/src/SwitchStateBaseHostif.cpp index 7a1d528c..c7266af5 100644 --- a/saivpp/src/SwitchStateBaseHostif.cpp +++ b/saivpp/src/SwitchStateBaseHostif.cpp @@ -765,6 +765,16 @@ sai_status_t SwitchStateBase::vpp_create_hostif_tap_interface( } SWSS_LOG_INFO("Successfully set mac to %s for %s", sai_serialize_mac(attr.value.mac).c_str(), name.c_str()); + // enable ipv6, which will set link local address based on mac. ipv4 can be enabled + // when ip is configured. + err = sw_interface_ip6_enable_disable(hwif_name, true); + if (err < 0) + { + SWSS_LOG_ERROR("failed to enable ipv6 for %s", hwif_name); + close(tapfd); + return SAI_STATUS_FAILURE; + } + setIfNameToPortId(name, obj_id); setPortIdToTapName(obj_id, name); diff --git a/saivpp/src/vppxlate/SaiVppXlate.c b/saivpp/src/vppxlate/SaiVppXlate.c index d975a8b1..fd45a0f5 100644 --- a/saivpp/src/vppxlate/SaiVppXlate.c +++ b/saivpp/src/vppxlate/SaiVppXlate.c @@ -113,7 +113,7 @@ #undef vl_endianfun -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) #define vl_printfun #include @@ -138,7 +138,7 @@ #undef vl_endianfun -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) #define vl_printfun #include @@ -163,7 +163,7 @@ #undef vl_endianfun -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) #define vl_printfun #include @@ -295,7 +295,7 @@ void os_exit(int code) {} #define WR(ret) \ do { \ f64 timeout = vat_time_now (vam) + 1.0; \ - socket_client_main_t *scm = vam->socket_client_main; \ + socket_client_main_t *scm = vam->socket_client_main; \ ret = -99; \ while (vat_time_now (vam) < timeout) { \ if (scm && scm->socket_enable) \ @@ -305,7 +305,7 @@ do { \ break; \ } \ vat_suspend (vam->vlib_main, 1e-5); \ - } \ + } \ } while(0); #define VPP_MAX_CTX 2 @@ -331,10 +331,10 @@ vpp_event_info_t * vpp_ev_dequeue () evp = vpp_evq_p->head; if (evp) { - vpp_evq_p->head = vpp_evq_p->head->next; + vpp_evq_p->head = vpp_evq_p->head->next; } if (vpp_evq_p->head == NULL) { - vpp_evq_p->tail = &vpp_evq_p->head; + vpp_evq_p->tail = &vpp_evq_p->head; } return evp; @@ -406,7 +406,7 @@ static void release_index (uint32_t idx) static uintptr_t get_index_ptr (uint32_t idx) { if (idx > VPP_MAX_CTX) { - return (uintptr_t) NULL; + return (uintptr_t) NULL; } return idx_map.ptr[idx]; @@ -518,19 +518,19 @@ static void set_reply_status (int retval) if (vam->async_mode) { - vam->async_errors += (retval < 0); + vam->async_errors += (retval < 0); } else { - vam->retval = retval; - vam->result_ready = 1; + vam->retval = retval; + vam->result_ready = 1; } } static void set_reply_sw_if_index (vl_api_interface_index_t sw_if_index) { vat_main_t *vam = &vat_main; - vam->sw_if_index = sw_if_index; + vam->sw_if_index = sw_if_index; } static void @@ -550,7 +550,7 @@ vl_api_want_interface_events_reply_t_handler (vl_api_want_interface_events_reply set_reply_status(ntohl(msg->retval)); SAIVPP_DEBUG("sw interface events enable %s(%d)", - msg->retval ? "failed" : "successful", msg->retval); + msg->retval ? "failed" : "successful", msg->retval); } static void @@ -562,36 +562,36 @@ vl_api_sw_interface_event_t_handler (vl_api_sw_interface_event_t *mp) sw_if_index = htonl(mp->sw_if_index); ptr = hash_get(interface_name_by_sw_index, sw_if_index); if (NULL == ptr) { - SAIVPP_WARN("vpp cannot get interface name for sw index %u", sw_if_index); - return; + SAIVPP_WARN("vpp cannot get interface name for sw index %u", sw_if_index); + return; } const char *hw_ifname = (const char *) ptr[0]; flags = htonl(mp->flags); if (flags & IF_STATUS_API_FLAG_ADMIN_UP && - !(flags & IF_STATUS_API_FLAG_LINK_UP)) { - return; + !(flags & IF_STATUS_API_FLAG_LINK_UP)) { + return; } bool link_up; if (flags & IF_STATUS_API_FLAG_LINK_UP) { - link_up = true; + link_up = true; } else { - link_up = false; + link_up = false; } SAIVPP_WARN("Sending vpp link %s event for interface %s index %u", - link_up ? "UP" : "DOWN", hw_ifname, sw_if_index); + link_up ? "UP" : "DOWN", hw_ifname, sw_if_index); vpp_event_info_t *evinfo; evinfo = calloc(1, sizeof(*evinfo)); if (evinfo) { - evinfo->type = VPP_INTF_LINK_STATUS; - vpp_intf_status_t *stp = &evinfo->data.intf_status; + evinfo->type = VPP_INTF_LINK_STATUS; + vpp_intf_status_t *stp = &evinfo->data.intf_status; - stp->link_up = link_up; - strncpy(stp->hwif_name, hw_ifname, sizeof(stp->hwif_name) -1); + stp->link_up = link_up; + strncpy(stp->hwif_name, hw_ifname, sizeof(stp->hwif_name) -1); - vpp_ev_enqueue(evinfo); + vpp_ev_enqueue(evinfo); } } @@ -607,7 +607,7 @@ vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t *mp) u8 *s = format (0, "%s%c", mp->interface_name, 0); hash_set_mem (vam->sw_if_index_by_interface_name, s, - ntohl (mp->sw_if_index)); + ntohl (mp->sw_if_index)); hash_set (interface_name_by_sw_index, ntohl (mp->sw_if_index), s); /* In sub interface case, fill the sub interface table entry */ @@ -619,7 +619,7 @@ vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t *mp) vec_validate (sub->interface_name, strlen ((char *) s) + 1); strncpy ((char *) sub->interface_name, (char *) s, - vec_len (sub->interface_name)); + vec_len (sub->interface_name)); sub->sw_if_index = ntohl (mp->sw_if_index); sub->sub_id = ntohl (mp->sub_id); @@ -734,6 +734,15 @@ vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *msg) SAIVPP_DEBUG("ip route add %s(%d)", msg->retval ? "failed" : "successful", msg->retval); } +static void +vl_api_sw_interface_ip6_enable_disable_reply_t_handler( + vl_api_sw_interface_ip6_enable_disable_reply_t *msg) +{ + set_reply_status(ntohl(msg->retval)); + + SAIVPP_DEBUG("ip6 enable/disable %s(%d)", msg->retval ? "failed" : "successful", msg->retval); +} + static void vl_api_set_ip_flow_hash_v2_reply_t_handler (vl_api_ip_route_add_del_reply_t *msg) { @@ -946,7 +955,7 @@ vl_api_tunterm_acl_add_replace_reply_t_handler(vl_api_tunterm_acl_add_replace_re *tunterm_index = ntohl(msg->tunterm_acl_index); SAIVPP_DEBUG("tunterm acl add_replace %s(%d) tunterm_index index %u", msg->retval ? "failed" : "successful", - msg->retval, *tunterm_index); + msg->retval, *tunterm_index); release_index(msg->context); } @@ -964,7 +973,7 @@ vl_api_tunterm_acl_interface_add_del_reply_t_handler(vl_api_tunterm_acl_interfac set_reply_status(ntohl(msg->retval)); SAIVPP_DEBUG("tunterm acl interface set/reset %s(%d)", msg->retval ? "failed" : "successful", - msg->retval); + msg->retval); } #define vl_api_get_first_msg_id_reply_t_handler vl_noop_handler @@ -1029,7 +1038,8 @@ static void vpp_base_vpe_init(void) _(INTERFACE_MSG_ID(SW_INTERFACE_EVENT), sw_interface_event) \ _(IP_MSG_ID(IP_TABLE_ADD_DEL_REPLY), ip_table_add_del_reply) \ _(IP_MSG_ID(IP_ROUTE_ADD_DEL_REPLY), ip_route_add_del_reply) \ - _(IP_MSG_ID(SET_IP_FLOW_HASH_V2_REPLY), set_ip_flow_hash_v2_reply) \ + _(IP_MSG_ID(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY), sw_interface_ip6_enable_disable_reply) \ + _(IP_MSG_ID(SET_IP_FLOW_HASH_V2_REPLY), set_ip_flow_hash_v2_reply) \ _(IP_NBR_MSG_ID(IP_NEIGHBOR_ADD_DEL_REPLY), ip_neighbor_add_del_reply) \ _(L2_MSG_ID(BRIDGE_DOMAIN_ADD_DEL_REPLY), bridge_domain_add_del_reply) \ _(L2_MSG_ID(SW_INTERFACE_SET_L2_BRIDGE_REPLY), sw_interface_set_l2_bridge_reply) \ @@ -1084,7 +1094,7 @@ static void vl_api_acl_add_replace_reply_t_handler(vl_api_acl_add_replace_reply_ *acl_index = ntohl(msg->acl_index); SAIVPP_DEBUG("acl add_replace %s(%d) acl index %u", msg->retval ? "failed" : "successful", - msg->retval, *acl_index); + msg->retval, *acl_index); release_index(msg->context); } @@ -1109,7 +1119,7 @@ vl_api_acl_interface_add_del_reply_t_handler(vl_api_acl_interface_add_del_reply_ set_reply_status(ntohl(msg->retval)); SAIVPP_DEBUG("acl interface set/reset %s(%d)", msg->retval ? "failed" : "successful", - msg->retval); + msg->retval); } #define LCP_MSG_ID(id) \ @@ -1126,7 +1136,7 @@ vl_api_acl_interface_add_del_reply_t_handler(vl_api_acl_interface_add_del_reply_ #define foreach_vpe_plugin_api_reply_msg \ _(LCP_MSG_ID(LCP_ITF_PAIR_ADD_DEL_REPLY), lcp_itf_pair_add_del_reply) \ - _(ACL_MSG_ID(ACL_ADD_REPLACE_REPLY), acl_add_replace_reply) \ + _(ACL_MSG_ID(ACL_ADD_REPLACE_REPLY), acl_add_replace_reply) \ _(ACL_MSG_ID(ACL_DEL_REPLY), acl_del_reply) \ _(ACL_MSG_ID(ACL_STATS_INTF_COUNTERS_ENABLE_REPLY), acl_stats_intf_counters_enable_reply) \ _(ACL_MSG_ID(ACL_INTERFACE_ADD_DEL_REPLY), acl_interface_add_del_reply) \ @@ -1431,7 +1441,7 @@ static int __delete_loopback (vat_main_t *vam, const char *hwif_name, u32 instan mp->sw_if_index = htonl(idx); } else { SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - VPP_UNLOCK(); + VPP_UNLOCK(); return -EINVAL; } @@ -1524,14 +1534,14 @@ int init_vpp_client() } dump_interface_table(vam); - vpp_acl_counters_enable_disable(true); + vpp_acl_counters_enable_disable(true); - /* - * SONiC periodically polls the port status so currently there is no need for - * async notification. This also simplifies the synchronous design of saivpp. - * Revisit the async mechanism if there is greater reason. - */ - vpp_intf_events_enable_disable(true); + /* + * SONiC periodically polls the port status so currently there is no need for + * async notification. This also simplifies the synchronous design of saivpp. + * Revisit the async mechanism if there is greater reason. + */ + vpp_intf_events_enable_disable(true); /* Register with VPP for BFD notifications */ vpp_bfd_events_enable_disable(true); @@ -1539,9 +1549,9 @@ int init_vpp_client() /* Enable BFD multihop support in VPP */ vpp_bfd_udp_enable_multihop(); - vpp_evq_init(); - vpp_client_init = 1; - return 0; + vpp_evq_init(); + vpp_client_init = 1; + return 0; } else { SAIVPP_ERROR("vpp socket connect failed\n"); } @@ -1555,7 +1565,7 @@ int refresh_interfaces_list () rc = api_sw_interface_dump(vam); if (rc == 0) { - SAIVPP_DEBUG("Interface dump available"); + SAIVPP_DEBUG("Interface dump available"); } dump_interface_table(vam); @@ -1609,7 +1619,7 @@ int delete_sub_interface (const char *hwif_name, u32 sub_id) } static int __set_interface_vrf (vat_main_t *vam, vl_api_interface_index_t if_idx, - u32 vrf_id, bool is_ipv6) + u32 vrf_id, bool is_ipv6) { vl_api_sw_interface_set_table_t *mp; int ret; @@ -1639,8 +1649,8 @@ int set_interface_vrf (const char *hwif_name, u32 sub_id, u32 vrf_id, bool is_ip char tmpbuf[64]; if (sub_id) { - snprintf(tmpbuf, sizeof(tmpbuf), "%s.%u", hwif_name, sub_id); - hwif_name = tmpbuf; + snprintf(tmpbuf, sizeof(tmpbuf), "%s.%u", hwif_name, sub_id); + hwif_name = tmpbuf; } idx = get_swif_idx(vam, hwif_name); SAIVPP_DEBUG("swif index of interface %s is %u\n", hwif_name, idx); @@ -1671,7 +1681,7 @@ static int vpp_intf_events_enable_disable (bool enable) } static int __ip_vrf_add_del (vat_main_t *vam, u32 vrf_id, - const char *vrf_name, bool is_ipv6, bool is_add) + const char *vrf_name, bool is_ipv6, bool is_add) { vl_api_ip_table_add_del_t *mp; int ret; @@ -1709,7 +1719,7 @@ int ip_vrf_del (u32 vrf_id, const char *vrf_name, bool is_ipv6) } static int __ip_nbr_add_del (vat_main_t *vam, vl_api_address_t *nbr_addr, u32 if_idx, - uint8_t *mac, bool is_static, bool no_fib_entry, bool is_add) + uint8_t *mac, bool is_static, bool no_fib_entry, bool is_add) { vl_api_ip_neighbor_add_del_t *mp; int ret; @@ -1739,21 +1749,21 @@ static int __ip_nbr_add_del (vat_main_t *vam, vl_api_address_t *nbr_addr, u32 if } static int ip_nbr_add_del (const char *hwif_name, uint32_t sw_if_index, struct sockaddr *addr, - bool is_static, bool no_fib_entry, uint8_t *mac, bool is_add) + bool is_static, bool no_fib_entry, uint8_t *mac, bool is_add) { vat_main_t *vam = &vat_main; vl_api_address_t api_addr; if (addr->sa_family == AF_INET) { - struct sockaddr_in *ip4 = (struct sockaddr_in *) addr; - api_addr.af = ADDRESS_IP4; - memcpy(api_addr.un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr.un.ip4)); + struct sockaddr_in *ip4 = (struct sockaddr_in *) addr; + api_addr.af = ADDRESS_IP4; + memcpy(api_addr.un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr.un.ip4)); } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *) addr; - api_addr.af = ADDRESS_IP6; - memcpy(api_addr.un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr.un.ip6)); + struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *) addr; + api_addr.af = ADDRESS_IP6; + memcpy(api_addr.un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr.un.ip6)); } else { - return -EINVAL; + return -EINVAL; } if (sw_if_index == ~0) { sw_if_index = get_swif_idx(vam, hwif_name); @@ -1796,63 +1806,63 @@ int ip_route_add_del (vpp_ip_route_t *prefix, bool is_add) addr = &prefix->prefix_addr; if (addr->sa_family == AF_INET) { - struct sockaddr_in *ip4 = &addr->addr.ip4; - api_addr->af = ADDRESS_IP4; - memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); + struct sockaddr_in *ip4 = &addr->addr.ip4; + api_addr->af = ADDRESS_IP4; + memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *ip6 = &addr->addr.ip6; - api_addr->af = ADDRESS_IP6; - memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); + struct sockaddr_in6 *ip6 = &addr->addr.ip6; + api_addr->af = ADDRESS_IP6; + memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } ip_route->prefix.len = prefix->prefix_len; ip_route->n_paths = path_count; for (unsigned int i = 0; i < path_count; i++) { - vpp_ip_nexthop_t *nexthop = &prefix->nexthop[i]; - vl_api_fib_path_t *fib_path = &ip_route->paths[i]; - vl_api_address_union_t *nh_addr = &fib_path->nh.address; - memset (fib_path, 0, sizeof (*fib_path)); - if (nexthop->sw_if_index != (u32) - 1) { - fib_path->sw_if_index = htonl(nexthop->sw_if_index); - } - else if (nexthop->hwif_name) { - idx = get_swif_idx(vam, nexthop->hwif_name); - if (idx != (u32) -1) { - fib_path->sw_if_index = htonl(idx); - } else { - printf("Unable to get sw_index for %s\n", nexthop->hwif_name); - } - } else { - fib_path->sw_if_index = htonl(~0); - } - - addr = &nexthop->addr; - - if (addr->sa_family == AF_INET) { - struct sockaddr_in *ip4 = &addr->addr.ip4; - memcpy(nh_addr->ip4, &ip4->sin_addr.s_addr, sizeof(nh_addr->ip4)); - fib_path->proto = htonl(FIB_API_PATH_NH_PROTO_IP4); - } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *ip6 = &addr->addr.ip6; - memcpy(nh_addr->ip6, &ip6->sin6_addr.s6_addr, sizeof(nh_addr->ip6)); - fib_path->proto = htonl(FIB_API_PATH_NH_PROTO_IP6); - } else { - VPP_UNLOCK(); - return -EINVAL; - } - if (nexthop->type == VPP_NEXTHOP_NORMAL) { - fib_path->type = htonl(FIB_API_PATH_TYPE_NORMAL); - } else if (nexthop->type == VPP_NEXTHOP_LOCAL) { - fib_path->type = htonl(FIB_API_PATH_TYPE_LOCAL); - } - fib_path->table_id = 0; - fib_path->rpf_id = htonl(~0); - fib_path->weight = nexthop->weight; - fib_path->preference = nexthop->preference; - fib_path->n_labels = 0; + vpp_ip_nexthop_t *nexthop = &prefix->nexthop[i]; + vl_api_fib_path_t *fib_path = &ip_route->paths[i]; + vl_api_address_union_t *nh_addr = &fib_path->nh.address; + memset (fib_path, 0, sizeof (*fib_path)); + if (nexthop->sw_if_index != (u32) - 1) { + fib_path->sw_if_index = htonl(nexthop->sw_if_index); + } + else if (nexthop->hwif_name) { + idx = get_swif_idx(vam, nexthop->hwif_name); + if (idx != (u32) -1) { + fib_path->sw_if_index = htonl(idx); + } else { + printf("Unable to get sw_index for %s\n", nexthop->hwif_name); + } + } else { + fib_path->sw_if_index = htonl(~0); + } + + addr = &nexthop->addr; + + if (addr->sa_family == AF_INET) { + struct sockaddr_in *ip4 = &addr->addr.ip4; + memcpy(nh_addr->ip4, &ip4->sin_addr.s_addr, sizeof(nh_addr->ip4)); + fib_path->proto = htonl(FIB_API_PATH_NH_PROTO_IP4); + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *ip6 = &addr->addr.ip6; + memcpy(nh_addr->ip6, &ip6->sin6_addr.s6_addr, sizeof(nh_addr->ip6)); + fib_path->proto = htonl(FIB_API_PATH_NH_PROTO_IP6); + } else { + VPP_UNLOCK(); + return -EINVAL; + } + if (nexthop->type == VPP_NEXTHOP_NORMAL) { + fib_path->type = htonl(FIB_API_PATH_TYPE_NORMAL); + } else if (nexthop->type == VPP_NEXTHOP_LOCAL) { + fib_path->type = htonl(FIB_API_PATH_TYPE_LOCAL); + } + fib_path->table_id = 0; + fib_path->rpf_id = htonl(~0); + fib_path->weight = nexthop->weight; + fib_path->preference = nexthop->preference; + fib_path->n_labels = 0; } ip_route->table_id = htonl(prefix->vrf_id); @@ -1916,57 +1926,57 @@ int vpp_acl_add_replace (vpp_acl_t *in_acl, uint32_t *acl_index, bool is_replace mp->count = htonl(acl_count); if (is_replace) { - mp->acl_index = htonl(*acl_index); + mp->acl_index = htonl(*acl_index); } else { - mp->acl_index = htonl(~0); + mp->acl_index = htonl(~0); } strncpy(mp->tag, in_acl->acl_name, sizeof (mp->tag) - 1); for (idx = 0; idx < acl_count; idx++) { - in_rule = &in_acl->rules[idx]; - vpp_rule = &mp->r[idx]; + in_rule = &in_acl->rules[idx]; + vpp_rule = &mp->r[idx]; addr = &in_rule->src_prefix; - api_addr = &vpp_rule->src_prefix.address; - - if (addr->sa_family == AF_INET) { - struct sockaddr_in *ip4 = &addr->addr.ip4; - api_addr->af = ADDRESS_IP4; - memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); - vpp_rule->src_prefix.len = ipv4_mask_len(in_rule->src_prefix_mask.addr.ip4.sin_addr.s_addr); - } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *ip6 = &addr->addr.ip6; - api_addr->af = ADDRESS_IP6; - memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); - vpp_rule->src_prefix.len = ipv6_mask_len(in_rule->src_prefix_mask.addr.ip6.sin6_addr.s6_addr); - } else { - SAIVPP_WARN("Unknown protocol in source prefix"); - /* return -EINVAL; */ - } + api_addr = &vpp_rule->src_prefix.address; + + if (addr->sa_family == AF_INET) { + struct sockaddr_in *ip4 = &addr->addr.ip4; + api_addr->af = ADDRESS_IP4; + memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); + vpp_rule->src_prefix.len = ipv4_mask_len(in_rule->src_prefix_mask.addr.ip4.sin_addr.s_addr); + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *ip6 = &addr->addr.ip6; + api_addr->af = ADDRESS_IP6; + memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); + vpp_rule->src_prefix.len = ipv6_mask_len(in_rule->src_prefix_mask.addr.ip6.sin6_addr.s6_addr); + } else { + SAIVPP_WARN("Unknown protocol in source prefix"); + /* return -EINVAL; */ + } addr = &in_rule->dst_prefix; - api_addr = &vpp_rule->dst_prefix.address; - - if (addr->sa_family == AF_INET) { - struct sockaddr_in *ip4 = &addr->addr.ip4; - api_addr->af = ADDRESS_IP4; - memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); - vpp_rule->dst_prefix.len = ipv4_mask_len(in_rule->dst_prefix_mask.addr.ip4.sin_addr.s_addr); - } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *ip6 = &addr->addr.ip6; - api_addr->af = ADDRESS_IP6; - memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); - vpp_rule->dst_prefix.len = ipv6_mask_len(in_rule->dst_prefix_mask.addr.ip6.sin6_addr.s6_addr); - } else { - SAIVPP_WARN("Unknown protocol in destination prefix"); - /* return -EINVAL; */ - } - - vpp_rule->proto = in_rule->proto; - vpp_rule->srcport_or_icmptype_first = htons(in_rule->srcport_or_icmptype_first); - vpp_rule->srcport_or_icmptype_last = htons(in_rule->srcport_or_icmptype_last); - vpp_rule->dstport_or_icmpcode_first = htons(in_rule->dstport_or_icmpcode_first); - vpp_rule->dstport_or_icmpcode_last = htons(in_rule->dstport_or_icmpcode_last); - vpp_rule->is_permit = in_rule->action; + api_addr = &vpp_rule->dst_prefix.address; + + if (addr->sa_family == AF_INET) { + struct sockaddr_in *ip4 = &addr->addr.ip4; + api_addr->af = ADDRESS_IP4; + memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); + vpp_rule->dst_prefix.len = ipv4_mask_len(in_rule->dst_prefix_mask.addr.ip4.sin_addr.s_addr); + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *ip6 = &addr->addr.ip6; + api_addr->af = ADDRESS_IP6; + memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); + vpp_rule->dst_prefix.len = ipv6_mask_len(in_rule->dst_prefix_mask.addr.ip6.sin6_addr.s6_addr); + } else { + SAIVPP_WARN("Unknown protocol in destination prefix"); + /* return -EINVAL; */ + } + + vpp_rule->proto = in_rule->proto; + vpp_rule->srcport_or_icmptype_first = htons(in_rule->srcport_or_icmptype_first); + vpp_rule->srcport_or_icmptype_last = htons(in_rule->srcport_or_icmptype_last); + vpp_rule->dstport_or_icmpcode_first = htons(in_rule->dstport_or_icmpcode_first); + vpp_rule->dstport_or_icmpcode_last = htons(in_rule->dstport_or_icmpcode_last); + vpp_rule->is_permit = in_rule->action; } mp->context = store_ptr(acl_index); @@ -2160,7 +2170,7 @@ static int vpp_acl_counters_enable_disable (bool enable) } int __vpp_acl_interface_bind_unbind (const char *hwif_name, uint32_t acl_index, - bool is_input, bool is_bind) + bool is_input, bool is_bind) { vat_main_t *vam = &vat_main; vl_api_acl_interface_add_del_t *mp; @@ -2172,19 +2182,19 @@ int __vpp_acl_interface_bind_unbind (const char *hwif_name, uint32_t acl_index, M (ACL_INTERFACE_ADD_DEL, mp); if (hwif_name) { - u32 idx; - - idx = get_swif_idx(vam, hwif_name); - if (idx != (u32) -1) { - mp->sw_if_index = htonl(idx); - } else { - SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - VPP_UNLOCK(); - return -EINVAL; - } + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } mp->is_input = is_input; mp->is_add = is_bind; @@ -2194,9 +2204,9 @@ int __vpp_acl_interface_bind_unbind (const char *hwif_name, uint32_t acl_index, W (ret); if (ret == VNET_API_ERROR_ACL_IN_USE_INBOUND || - ret == VNET_API_ERROR_ACL_IN_USE_OUTBOUND) { - SAIVPP_WARN("ACL index %u is already bound to %s", acl_index, hwif_name); - ret = 0; + ret == VNET_API_ERROR_ACL_IN_USE_OUTBOUND) { + SAIVPP_WARN("ACL index %u is already bound to %s", acl_index, hwif_name); + ret = 0; } VPP_UNLOCK(); @@ -2204,13 +2214,13 @@ int __vpp_acl_interface_bind_unbind (const char *hwif_name, uint32_t acl_index, } int vpp_acl_interface_bind (const char *hwif_name, uint32_t acl_index, - bool is_input) + bool is_input) { __vpp_acl_interface_bind_unbind(hwif_name, acl_index, is_input, true); } int vpp_acl_interface_unbind (const char *hwif_name, uint32_t acl_index, - bool is_input) + bool is_input) { __vpp_acl_interface_bind_unbind(hwif_name, acl_index, is_input, false); } @@ -2263,32 +2273,32 @@ int interface_ip_address_add_del (const char *hwif_name, vpp_ip_route_t *prefix, addr = &prefix->prefix_addr; if (addr->sa_family == AF_INET) { - struct sockaddr_in *ip4 = &addr->addr.ip4; - api_addr->af = ADDRESS_IP4; - memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); + struct sockaddr_in *ip4 = &addr->addr.ip4; + api_addr->af = ADDRESS_IP4; + memcpy(api_addr->un.ip4, &ip4->sin_addr.s_addr, sizeof(api_addr->un.ip4)); } else if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *ip6 = &addr->addr.ip6; - api_addr->af = ADDRESS_IP6; - memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); + struct sockaddr_in6 *ip6 = &addr->addr.ip6; + api_addr->af = ADDRESS_IP6; + memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } mp->prefix.len = prefix->prefix_len; if (hwif_name) { - u32 idx; - - idx = get_swif_idx(vam, hwif_name); - if (idx != (u32) -1) { - mp->sw_if_index = htonl(idx); - } else { - SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - return -EINVAL; - } + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + return -EINVAL; + } } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } mp->is_add = is_add; @@ -2315,19 +2325,19 @@ int interface_set_state (const char *hwif_name, bool is_up) M (SW_INTERFACE_SET_FLAGS, mp); if (hwif_name) { - u32 idx; - - idx = get_swif_idx(vam, hwif_name); - if (idx != (u32) -1) { - mp->sw_if_index = htonl(idx); - } else { - SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - VPP_UNLOCK(); - return -EINVAL; - } + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } mp->flags = htonl ((is_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0); @@ -2354,19 +2364,19 @@ int interface_get_state (const char *hwif_name, bool *link_is_up) M (SW_INTERFACE_DUMP, mp); if (hwif_name) { - u32 idx; - - idx = get_swif_idx(vam, hwif_name); - if (idx != (u32) -1) { - mp->sw_if_index = htonl(idx); - } else { - SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - VPP_UNLOCK(); - return -EINVAL; - } + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } mp->context = store_ptr(link_is_up); @@ -2418,31 +2428,31 @@ int sw_interface_set_mtu (const char *hwif_name, uint32_t mtu, int type) M (SW_INTERFACE_SET_MTU, mp); if (hwif_name) { - u32 idx; - - idx = get_swif_idx(vam, hwif_name); - if (idx != (u32) -1) { - mp->sw_if_index = htonl(idx); - } else { - SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - VPP_UNLOCK(); - return -EINVAL; - } + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } switch (type) { case AF_INET: - mp->mtu[MTU_PROTO_API_IP4] = htonl(mtu); - break; + mp->mtu[MTU_PROTO_API_IP4] = htonl(mtu); + break; case AF_INET6: - mp->mtu[MTU_PROTO_API_IP6] = htonl(mtu); - break; + mp->mtu[MTU_PROTO_API_IP6] = htonl(mtu); + break; default: - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } S (mp); @@ -2510,19 +2520,19 @@ int hw_interface_set_mtu (const char *hwif_name, uint32_t mtu) M (HW_INTERFACE_SET_MTU, mp); if (hwif_name) { - u32 idx; - - idx = get_swif_idx(vam, hwif_name); - if (idx != (u32) -1) { - mp->sw_if_index = htonl(idx); - } else { - SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - VPP_UNLOCK(); - return -EINVAL; - } + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } mp->mtu = htons(mtu); @@ -2535,6 +2545,43 @@ int hw_interface_set_mtu (const char *hwif_name, uint32_t mtu) return ret; } +int sw_interface_ip6_enable_disable(const char *hwif_name, bool enable) +{ + vat_main_t *vam = &vat_main; + vl_api_sw_interface_ip6_enable_disable_t *mp; + int ret; + + VPP_LOCK(); + + __plugin_msg_base = ip_msg_id_base; + + M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp); + if (hwif_name) { + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } + } else { + VPP_UNLOCK(); + return -EINVAL; + } + mp->enable = enable; + + S (mp); + + WR (ret); + + VPP_UNLOCK(); + + return ret; +} + int vpp_bridge_domain_add_del(uint32_t bridge_id, bool is_add) { vat_main_t *vam = &vat_main; @@ -2597,7 +2644,7 @@ int set_sw_interface_l2_bridge(const char *hwif_name, uint32_t bridge_id, bool l vat_main_t *vam = &vat_main; if (hwif_name) { - u32 idx; + u32 idx; idx = get_swif_idx(vam, hwif_name); if (idx != (u32) -1) { @@ -2703,9 +2750,9 @@ int create_bvi_interface(uint8_t *mac_address, u32 instance) M (BVI_CREATE, mp); if (mac_address == NULL) { - SAIVPP_ERROR("Invalid mac address \n"); - VPP_UNLOCK(); - return -EINVAL; + SAIVPP_ERROR("Invalid mac address \n"); + VPP_UNLOCK(); + return -EINVAL; } mp->user_instance = htonl(instance); @@ -2733,19 +2780,19 @@ int delete_bvi_interface(const char *hwif_name) M (BVI_DELETE, mp); if (hwif_name) { - u32 idx; - - idx = get_swif_idx(vam, hwif_name); - if (idx != (u32) -1) { - mp->sw_if_index = htonl(idx); - } else { - SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); - VPP_UNLOCK(); - return -EINVAL; - } + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } S (mp); @@ -2809,8 +2856,8 @@ int vpp_vxlan_tunnel_add_del(vpp_vxlan_tunnel_t *tunnel, bool is_add, u32 *sw_if api_addr->af = ADDRESS_IP6; memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } api_addr = &mp->dst_address; @@ -2824,8 +2871,8 @@ int vpp_vxlan_tunnel_add_del(vpp_vxlan_tunnel_t *tunnel, bool is_add, u32 *sw_if api_addr->af = ADDRESS_IP6; memcpy(api_addr->un.ip6, &ip6->sin6_addr.s6_addr, sizeof(api_addr->un.ip6)); } else { - VPP_UNLOCK(); - return -EINVAL; + VPP_UNLOCK(); + return -EINVAL; } mp->src_port = htons(tunnel->src_port); diff --git a/saivpp/src/vppxlate/SaiVppXlate.h b/saivpp/src/vppxlate/SaiVppXlate.h index 41d26a58..89cbcf4e 100644 --- a/saivpp/src/vppxlate/SaiVppXlate.h +++ b/saivpp/src/vppxlate/SaiVppXlate.h @@ -219,6 +219,7 @@ typedef enum { extern int hw_interface_set_mtu(const char *hwif_name, uint32_t mtu); extern int sw_interface_set_mtu(const char *hwif_name, uint32_t mtu, int type); extern int sw_interface_set_mac(const char *hwif_name, uint8_t *mac_address); + extern int sw_interface_ip6_enable_disable(const char *hwif_name, bool enable); extern int ip_vrf_add(uint32_t vrf_id, const char *vrf_name, bool is_ipv6); extern int ip_vrf_del(uint32_t vrf_id, const char *vrf_name, bool is_ipv6); From 64b4e722748cebcdfe576387466cb32f632bb23f Mon Sep 17 00:00:00 2001 From: Yue Gao Date: Wed, 29 Jan 2025 14:44:46 -0800 Subject: [PATCH 2/2] Handle linklocal routes --- saivpp/src/SwitchStateBaseNexthop.cpp | 37 +++++- saivpp/src/SwitchStateBaseNexthop.h | 1 + saivpp/src/SwitchStateBaseRoute.cpp | 11 +- vppbld/vpp.patch | 168 +++++++++++++++++++++++++- 4 files changed, 203 insertions(+), 14 deletions(-) diff --git a/saivpp/src/SwitchStateBaseNexthop.cpp b/saivpp/src/SwitchStateBaseNexthop.cpp index f551c11e..6072f606 100644 --- a/saivpp/src/SwitchStateBaseNexthop.cpp +++ b/saivpp/src/SwitchStateBaseNexthop.cpp @@ -194,9 +194,36 @@ SwitchStateBase::fillNHGrpMember(nexthop_grp_member_t *nxt_grp_member, sai_objec switch (next_hop_type) { case SAI_NEXT_HOP_TYPE_IP: - attr.id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; - if (get(SAI_OBJECT_TYPE_NEXT_HOP, next_hop_oid, 1, &attr) == SAI_STATUS_SUCCESS) { - nxt_grp_member->rif_oid = attr.value.oid; + { + uint32_t rif_type; + sai_object_id_t port_oid; + uint16_t vlan_id = 0; + attr.id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; + if (nh_obj->get_attr(attr) == SAI_STATUS_SUCCESS) + { + nxt_grp_member->rif_oid = attr.value.oid; + } + auto rif_obj = nh_obj->get_linked_object(SAI_OBJECT_TYPE_ROUTER_INTERFACE, SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID); + + attr.id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID; + CHECK_STATUS_QUIET(rif_obj->get_mandatory_attr(attr)); + port_oid = attr.value.oid; + + attr.id = SAI_ROUTER_INTERFACE_ATTR_TYPE; + CHECK_STATUS_QUIET(rif_obj->get_mandatory_attr(attr)); + rif_type = attr.value.u16; + if (rif_type == SAI_ROUTER_INTERFACE_TYPE_SUB_PORT) { + attr.id = SAI_ROUTER_INTERFACE_ATTR_OUTER_VLAN_ID; + CHECK_STATUS_QUIET(rif_obj->get_mandatory_attr(attr)); + vlan_id = attr.value.u16; + } + std::string if_name; + if (vpp_get_hwif_name(port_oid, vlan_id, if_name)) { + strncpy(nxt_grp_member->if_name, if_name.c_str(), sizeof(nxt_grp_member->if_name) - 1); + } else { + nxt_grp_member->if_name[0] = 0; + } + break; } break; case SAI_NEXT_HOP_TYPE_TUNNEL_ENCAP: { @@ -231,7 +258,7 @@ SwitchStateBase::createNexthop( SWSS_LOG_ENTER(); CHECK_STATUS(find_attrib_in_list(attr_count, attr_list, SAI_NEXT_HOP_ATTR_TYPE, &next_hop_type, &attr_index)); - if (next_hop_type->s32 == SAI_NEXT_HOP_TYPE_TUNNEL_ENCAP) { + if (next_hop_type->u32 == SAI_NEXT_HOP_TYPE_TUNNEL_ENCAP) { //Deligate the creation of tunnel encap nexthop to tunnel manager CHECK_STATUS(m_tunnel_mgr.create_tunnel_encap_nexthop(serializedObjectId, switch_id, attr_count, attr_list)); } @@ -254,7 +281,7 @@ sai_status_t SwitchStateBase::removeNexthop( if(status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Missing SAI_NEXT_HOP_ATTR_TYPE in %s", serializedObjectId); } - else if (attr.value.s32 == SAI_NEXT_HOP_TYPE_TUNNEL_ENCAP) { + else if (attr.value.u32 == SAI_NEXT_HOP_TYPE_TUNNEL_ENCAP) { CHECK_STATUS(m_tunnel_mgr.remove_tunnel_encap_nexthop(serializedObjectId)); } } diff --git a/saivpp/src/SwitchStateBaseNexthop.h b/saivpp/src/SwitchStateBaseNexthop.h index 27c77c94..46919717 100644 --- a/saivpp/src/SwitchStateBaseNexthop.h +++ b/saivpp/src/SwitchStateBaseNexthop.h @@ -25,6 +25,7 @@ typedef struct nexthop_grp_member_ { uint32_t weight; uint32_t seq_id; uint32_t sw_if_index; + char if_name[64]; } nexthop_grp_member_t; typedef struct nexthop_grp_config_ { diff --git a/saivpp/src/SwitchStateBaseRoute.cpp b/saivpp/src/SwitchStateBaseRoute.cpp index 1f5a2449..af413447 100644 --- a/saivpp/src/SwitchStateBaseRoute.cpp +++ b/saivpp/src/SwitchStateBaseRoute.cpp @@ -70,7 +70,6 @@ void create_route_prefix_entry ( void create_vpp_nexthop_entry ( nexthop_grp_member_t *nxt_grp_member, - const char *hwif_name, vpp_nexthop_type_e type, vpp_ip_nexthop_t *vpp_nexthop) { @@ -97,7 +96,12 @@ void create_vpp_nexthop_entry ( } } vpp_nexthop->type = type; - vpp_nexthop->hwif_name = hwif_name; + + if (strlen(nxt_grp_member->if_name) > 0) { + vpp_nexthop->hwif_name = nxt_grp_member->if_name; + } else { + vpp_nexthop->hwif_name = NULL; + } vpp_nexthop->sw_if_index = nxt_grp_member->sw_if_index; vpp_nexthop->weight = (uint8_t) nxt_grp_member->weight; vpp_nexthop->preference = 0; @@ -120,7 +124,6 @@ sai_status_t SwitchStateBase::IpRouteAddRemove( next_hop_oid = attr.value.oid; sai_route_entry_t route_entry; - const char *hwif_name = NULL; vpp_nexthop_type_e nexthop_type = VPP_NEXTHOP_NORMAL; bool config_ip_route = false; @@ -182,7 +185,7 @@ sai_status_t SwitchStateBase::IpRouteAddRemove( size_t i; for (i = 0; i < nxthop_group->nmembers; i++) { - create_vpp_nexthop_entry(nxt_grp_member, hwif_name, nexthop_type, &ip_route->nexthop[i]); + create_vpp_nexthop_entry(nxt_grp_member, nexthop_type, &ip_route->nexthop[i]); nxt_grp_member++; } ip_route->nexthop_cnt = nxthop_group->nmembers; diff --git a/vppbld/vpp.patch b/vppbld/vpp.patch index 74a60168..ac0bee94 100644 --- a/vppbld/vpp.patch +++ b/vppbld/vpp.patch @@ -1,8 +1,8 @@ diff --git a/Makefile b/Makefile -index 98866e9be..f9d5b349e 100644 +index 3144905f3..04560cf2c 100644 --- a/Makefile +++ b/Makefile -@@ -76,7 +76,7 @@ DEB_DEPENDS += libffi-dev python3-ply libunwind-dev +@@ -78,7 +78,7 @@ DEB_DEPENDS += libffi-dev python3-ply libunwind-dev DEB_DEPENDS += cmake ninja-build python3-jsonschema python3-yaml DEB_DEPENDS += python3-venv # ensurepip DEB_DEPENDS += python3-dev python3-pip @@ -11,7 +11,7 @@ index 98866e9be..f9d5b349e 100644 # DEB_DEPENDS += enchant # for docs DEB_DEPENDS += python3-virtualenv DEB_DEPENDS += libssl-dev -@@ -85,7 +85,7 @@ DEB_DEPENDS += iperf3 # for 'make test TEST=vcl' +@@ -87,7 +87,7 @@ DEB_DEPENDS += iperf3 # for 'make test TEST=vcl' DEB_DEPENDS += nasm DEB_DEPENDS += iperf ethtool # for 'make test TEST=vm_vpp_interfaces' DEB_DEPENDS += libpcap-dev @@ -21,10 +21,10 @@ index 98866e9be..f9d5b349e 100644 LIBFFI=libffi6 # works on all but 20.04 and debian-testing diff --git a/build/external/packages/xdp-tools.mk b/build/external/packages/xdp-tools.mk -index b9285971f..c38acc598 100644 +index 08d94e424..1fbbef9b7 100644 --- a/build/external/packages/xdp-tools.mk +++ b/build/external/packages/xdp-tools.mk -@@ -24,7 +24,7 @@ define xdp-tools_config_cmds +@@ -25,7 +25,7 @@ define xdp-tools_config_cmds endef define xdp-tools_build_cmds @@ -33,6 +33,164 @@ index b9285971f..c38acc598 100644 endef define xdp-tools_install_cmds +diff --git a/src/plugins/linux-cp/lcp_node.c b/src/plugins/linux-cp/lcp_node.c +index 241cc5e4b..5438d536d 100644 +--- a/src/plugins/linux-cp/lcp_node.c ++++ b/src/plugins/linux-cp/lcp_node.c +@@ -1033,6 +1033,153 @@ VNET_FEATURE_INIT (lcp_arp_host_arp_feat, static) = { + .runs_before = VNET_FEATURES ("arp-reply"), + }; + ++typedef struct l2_punt_trace_t_ ++{ ++ u8 direction; // 0 = punt, 1 = inject ++ u32 phy_sw_if_index; ++ u32 host_sw_if_index; ++} l2_punt_trace_t; ++ ++static u8 * ++format_l2_punt_trace (u8 *s, va_list *args) ++{ ++ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); ++ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); ++ l2_punt_trace_t *t = va_arg (*args, l2_punt_trace_t *); ++ ++ if (t->direction) ++ { ++ s = format (s, "l2-punt: %u -> %u", t->host_sw_if_index, ++ t->phy_sw_if_index); ++ } ++ else ++ { ++ s = format (s, "l2-punt: %u -> %u", t->phy_sw_if_index, ++ t->host_sw_if_index); ++ } ++ ++ return s; ++} ++ ++VLIB_NODE_FN (l2_punt_node) ++(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) ++{ ++ u32 n_left_from, *from, *to_next, n_left_to_next; ++ lip_punt_next_t next_index; ++ ++ next_index = node->cached_next_index; ++ n_left_from = frame->n_vectors; ++ from = vlib_frame_vector_args (frame); ++ ++ while (n_left_from > 0) ++ { ++ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); ++ ++ while (n_left_from > 0 && n_left_to_next > 0) ++ { ++ vlib_buffer_t *b0; ++ const lcp_itf_pair_t *lip0 = NULL; ++ u32 next0 = ~0; ++ u32 bi0, lipi0; ++ u32 sw_if_index0; ++ u8 direction = 0; ++ u8 len0; ++ ++ bi0 = to_next[0] = from[0]; ++ ++ from += 1; ++ to_next += 1; ++ n_left_from -= 1; ++ n_left_to_next -= 1; ++ next0 = LIP_PUNT_NEXT_DROP; ++ ++ b0 = vlib_get_buffer (vm, bi0); ++ ++ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; ++ // check if RX sw_if_index is a phy (meaning this could require a punt, direction = 0) ++ lipi0 = lcp_itf_pair_find_by_phy (sw_if_index0); ++ if (lipi0 == INDEX_INVALID) ++ { ++ // check if RX sw_if_index is a host (meaning this could require an inject, direction = 1) ++ lipi0 = lcp_itf_pair_find_by_host (sw_if_index0); ++ if (lipi0 == INDEX_INVALID) ++ goto trace0; ++ ++ direction = 1; ++ } ++ ++ lip0 = lcp_itf_pair_get (lipi0); ++ next0 = LIP_PUNT_NEXT_IO; ++ // if direction is 1 (inject), set TX to phy ++ // if direction is 0 (punt), set TX to host ++ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ++ direction ? lip0->lip_phy_sw_if_index : lip0->lip_host_sw_if_index; ++ ++ if (PREDICT_TRUE (lip0->lip_host_type == LCP_ITF_HOST_TAP)) ++ { ++ /* ++ * rewind to ethernet header ++ */ ++ len0 = ((u8 *) vlib_buffer_get_current (b0) - ++ (u8 *) ethernet_buffer_get_header (b0)); ++ vlib_buffer_advance (b0, -len0); ++ } ++ ++ trace0: ++ if (PREDICT_FALSE ((b0->flags & VLIB_BUFFER_IS_TRACED))) ++ { ++ l2_punt_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); ++ t->direction = direction; ++ if (direction) ++ { ++ t->phy_sw_if_index = ++ (lipi0 == INDEX_INVALID) ? ~0 : lip0->lip_phy_sw_if_index; ++ t->host_sw_if_index = sw_if_index0; ++ } ++ else ++ { ++ ++ t->phy_sw_if_index = sw_if_index0; ++ t->host_sw_if_index = ++ (lipi0 == INDEX_INVALID) ? ~0 : lip0->lip_host_sw_if_index; ++ } ++ } ++ ++ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, ++ n_left_to_next, bi0, next0); ++ } ++ ++ vlib_put_next_frame (vm, node, next_index, n_left_to_next); ++ } ++ ++ return frame->n_vectors; ++} ++ ++VLIB_REGISTER_NODE (l2_punt_node) = { ++ .name = "linux-cp-punt-l2", ++ .vector_size = sizeof (u32), ++ .format_trace = format_l2_punt_trace, ++ .type = VLIB_NODE_TYPE_INTERNAL, ++ ++ .n_next_nodes = LIP_PUNT_N_NEXT, ++ .next_nodes = { ++ [LIP_PUNT_NEXT_DROP] = "error-drop", ++ [LIP_PUNT_NEXT_IO] = "interface-output", ++ }, ++ }; ++ ++static clib_error_t * ++lcp_lacp_init (vlib_main_t *vm) ++{ ++ ethernet_register_input_type (vm, ETHERNET_TYPE_SLOW_PROTOCOLS /* LACP */ , ++ l2_punt_node.index); ++ icmp6_register_type (vm, ICMP6_router_solicitation, l2_punt_node.index); ++ icmp6_register_type (vm, ICMP6_router_advertisement, l2_punt_node.index); ++ ++ return NULL; ++} ++ ++VLIB_INIT_FUNCTION (lcp_lacp_init); + /* + * fd.io coding-style-patch-verification: ON + * diff --git a/src/plugins/vxlan/vxlan.c b/src/plugins/vxlan/vxlan.c index 0885550d2..8b8cd66e4 100644 --- a/src/plugins/vxlan/vxlan.c