]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_evpn_vty.c
Merge pull request #5703 from ton31337/feature/limit_outgoing_prefixes
[mirror_frr.git] / bgpd / bgp_evpn_vty.c
index 2344db2e8d394ad5a8a0ecc1430b40e1e0fa9cdf..3049a00ce3205822958d66b8738de902c7e547c2 100644 (file)
@@ -275,42 +275,61 @@ static void show_import_rt_entry(struct hash_bucket *bucket, void *args[])
 
 static void bgp_evpn_show_route_rd_header(struct vty *vty,
                                          struct bgp_node *rd_rn,
-                                         json_object *json)
+                                         json_object *json,
+                                         char *rd_str, int len)
 {
        uint16_t type;
        struct rd_as rd_as;
        struct rd_ip rd_ip;
        uint8_t *pnt;
-       char rd_str[RD_ADDRSTRLEN];
 
        pnt = rd_rn->p.u.val;
 
        /* Decode RD type. */
        type = decode_rd_type(pnt);
 
-       if (json)
-               return;
-
-       vty_out(vty, "Route Distinguisher: ");
+       if (!json)
+               vty_out(vty, "Route Distinguisher: ");
 
        switch (type) {
        case RD_TYPE_AS:
                decode_rd_as(pnt + 2, &rd_as);
-               snprintf(rd_str, RD_ADDRSTRLEN, "%u:%d", rd_as.as, rd_as.val);
+               snprintf(rd_str, len, "%u:%d", rd_as.as, rd_as.val);
+               if (json)
+                       json_object_string_add(json, "rd", rd_str);
+               else
+                       vty_out(vty, "%s\n", rd_str);
+               break;
+
+       case RD_TYPE_AS4:
+               decode_rd_as4(pnt + 2, &rd_as);
+               snprintf(rd_str, len, "%u:%d", rd_as.as, rd_as.val);
+               if (json)
+                       json_object_string_add(json, "rd", rd_str);
+               else
+                       vty_out(vty, "%s\n", rd_str);
                break;
 
        case RD_TYPE_IP:
                decode_rd_ip(pnt + 2, &rd_ip);
-               snprintf(rd_str, RD_ADDRSTRLEN, "%s:%d", inet_ntoa(rd_ip.ip),
+               snprintf(rd_str, len, "%s:%d", inet_ntoa(rd_ip.ip),
                         rd_ip.val);
+               if (json)
+                       json_object_string_add(json, "rd", rd_str);
+               else
+                       vty_out(vty, "%s\n", rd_str);
                break;
 
        default:
-               snprintf(rd_str, RD_ADDRSTRLEN, "Unknown RD type");
+               if (json) {
+                       snprintf(rd_str, len, "Unknown");
+                       json_object_string_add(json, "rd", rd_str);
+               } else {
+                       snprintf(rd_str, len, "Unknown RD type");
+                       vty_out(vty, "%s\n", rd_str);
+               }
                break;
        }
-
-       vty_out(vty, "%s\n", rd_str);
 }
 
 static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp,
@@ -345,6 +364,7 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
        struct ecommunity *ecom;
        json_object *json_import_rtl = NULL;
        json_object *json_export_rtl = NULL;
+       char buf2[ETHER_ADDR_STRLEN];
 
        json_import_rtl = json_export_rtl = 0;
 
@@ -360,6 +380,22 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
                json_object_string_add(json, "originatorIp",
                                       inet_ntoa(bgp_vrf->originator_ip));
                json_object_string_add(json, "advertiseGatewayMacip", "n/a");
+               json_object_string_add(json, "advertiseSviMacip", "n/a");
+               json_object_to_json_string_ext(json,
+                                              JSON_C_TO_STRING_NOSLASHESCAPE);
+               json_object_string_add(json, "advertisePip",
+                                      bgp_vrf->evpn_info->advertise_pip ?
+                                      "Enabled" : "Disabled");
+               json_object_string_add(json, "sysIP",
+                                      inet_ntop(AF_INET,
+                                       &bgp_vrf->evpn_info->pip_ip,
+                                       buf1, INET_ADDRSTRLEN));
+               json_object_string_add(json, "sysMac",
+                               prefix_mac2str(&bgp_vrf->evpn_info->pip_rmac,
+                                              buf2, sizeof(buf2)));
+               json_object_string_add(json, "rmac",
+                               prefix_mac2str(&bgp_vrf->rmac,
+                                              buf2, sizeof(buf2)));
        } else {
                vty_out(vty, "VNI: %d", bgp_vrf->l3vni);
                vty_out(vty, " (known to the kernel)");
@@ -373,6 +409,18 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
                vty_out(vty, "  Originator IP: %s\n",
                        inet_ntoa(bgp_vrf->originator_ip));
                vty_out(vty, "  Advertise-gw-macip : %s\n", "n/a");
+               vty_out(vty, "  Advertise-svi-macip : %s\n", "n/a");
+               vty_out(vty, "  Advertise-pip: %s\n",
+                       bgp_vrf->evpn_info->advertise_pip ? "Yes" : "No");
+               vty_out(vty, "  System-IP: %s\n",
+                       inet_ntop(AF_INET, &bgp_vrf->evpn_info->pip_ip,
+                                 buf1, INET_ADDRSTRLEN));
+               vty_out(vty, "  System-MAC: %s\n",
+                               prefix_mac2str(&bgp_vrf->evpn_info->pip_rmac,
+                                              buf2, sizeof(buf2)));
+               vty_out(vty, "  Router-MAC: %s\n",
+                               prefix_mac2str(&bgp_vrf->rmac,
+                                              buf2, sizeof(buf2)));
        }
 
        if (!json)
@@ -462,6 +510,9 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
        struct ecommunity *ecom;
        json_object *json_import_rtl = NULL;
        json_object *json_export_rtl = NULL;
+       struct bgp *bgp_evpn;
+
+       bgp_evpn = bgp_get_evpn();
 
        if (json) {
                json_import_rtl = json_object_new_array();
@@ -477,8 +528,30 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
                                       inet_ntoa(vpn->originator_ip));
                json_object_string_add(json, "mcastGroup",
                                inet_ntoa(vpn->mcast_grp));
-               json_object_string_add(json, "advertiseGatewayMacip",
-                                      vpn->advertise_gw_macip ? "Yes" : "No");
+               /* per vni knob is enabled -- Enabled
+                * Global knob is enabled  -- Active
+                * default  -- Disabled
+                */
+               if (!vpn->advertise_gw_macip &&
+                   bgp_evpn && bgp_evpn->advertise_gw_macip)
+                       json_object_string_add(json, "advertiseGatewayMacip",
+                                              "Active");
+               else if (vpn->advertise_gw_macip)
+                       json_object_string_add(json, "advertiseGatewayMacip",
+                                              "Enabled");
+               else
+                       json_object_string_add(json, "advertiseGatewayMacip",
+                                              "Disabled");
+               if (!vpn->advertise_svi_macip && bgp_evpn &&
+                   bgp_evpn->evpn_info->advertise_svi_macip)
+                       json_object_string_add(json, "advertiseSviMacip",
+                                              "Active");
+               else if (vpn->advertise_svi_macip)
+                       json_object_string_add(json, "advertiseSviMacip",
+                                              "Enabled");
+               else
+                       json_object_string_add(json, "advertiseSviMacip",
+                                              "Disabled");
        } else {
                vty_out(vty, "VNI: %d", vpn->vni);
                if (is_vni_live(vpn))
@@ -494,10 +567,26 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
                        inet_ntoa(vpn->originator_ip));
                vty_out(vty, "  Mcast group: %s\n",
                                inet_ntoa(vpn->mcast_grp));
-               vty_out(vty, "  Advertise-gw-macip : %s\n",
-                       vpn->advertise_gw_macip ? "Yes" : "No");
-               vty_out(vty, "  Advertise-svi-macip : %s\n",
-                       vpn->advertise_svi_macip ? "Yes" : "No");
+               if (!vpn->advertise_gw_macip &&
+                   bgp_evpn && bgp_evpn->advertise_gw_macip)
+                       vty_out(vty, "  Advertise-gw-macip : %s\n",
+                               "Active");
+               else if (vpn->advertise_gw_macip)
+                       vty_out(vty, "  Advertise-gw-macip : %s\n",
+                               "Enabled");
+               else
+                       vty_out(vty, "  Advertise-gw-macip : %s\n",
+                               "Disabled");
+               if (!vpn->advertise_svi_macip && bgp_evpn &&
+                   bgp_evpn->evpn_info->advertise_svi_macip)
+                       vty_out(vty, "  Advertise-svi-macip : %s\n",
+                               "Active");
+               else if (vpn->advertise_svi_macip)
+                       vty_out(vty, "  Advertise-svi-macip : %s\n",
+                               "Enabled");
+               else
+                       vty_out(vty, "  Advertise-svi-macip : %s\n",
+                               "Disabled");
        }
 
        if (!json)
@@ -1012,18 +1101,17 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
        struct bgp_path_info *pi;
        int rd_header;
        int header = 1;
-       char rd_str[BUFSIZ];
+       char rd_str[RD_ADDRSTRLEN];
        char buf[BUFSIZ];
        int no_display;
 
        unsigned long output_count = 0;
        unsigned long total_count = 0;
        json_object *json = NULL;
-       json_object *json_nroute = NULL;
        json_object *json_array = NULL;
        json_object *json_prefix_info = NULL;
 
-       memset(rd_str, 0, BUFSIZ);
+       memset(rd_str, 0, RD_ADDRSTRLEN);
 
        bgp = bgp_get_evpn();
        if (bgp == NULL) {
@@ -1040,6 +1128,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
        for (rn = bgp_table_top(bgp->rib[afi][SAFI_EVPN]); rn;
             rn = bgp_route_next(rn)) {
                uint64_t tbl_ver;
+               json_object *json_nroute = NULL;
 
                if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
                        continue;
@@ -1057,22 +1146,6 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
                                continue;
 
                        no_display = 0;
-                       if (use_json) {
-                               json_array = json_object_new_array();
-                               json_prefix_info = json_object_new_object();
-
-                               json_object_string_add(json_prefix_info,
-                                       "prefix", bgp_evpn_route2str(
-                                       (struct prefix_evpn *)&rm->p, buf,
-                                       BUFSIZ));
-
-                               json_object_int_add(json_prefix_info,
-                                       "prefixLen", rm->p.prefixlen);
-
-                               if (rd_header)
-                                       json_nroute = json_object_new_object();
-                       }
-
                        for (; pi; pi = pi->next) {
                                total_count++;
                                if (type == bgp_show_type_neighbor) {
@@ -1146,60 +1219,16 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
                                        header = 0;
                                }
                                if (rd_header) {
-                                       uint16_t type;
-                                       struct rd_as rd_as;
-                                       struct rd_ip rd_ip;
-                                       uint8_t *pnt;
-
-                                       pnt = rn->p.u.val;
-
-                                       /* Decode RD type. */
-                                       type = decode_rd_type(pnt);
-                                       /* Decode RD value. */
-                                       if (type == RD_TYPE_AS)
-                                               decode_rd_as(pnt + 2, &rd_as);
-                                       else if (type == RD_TYPE_AS4)
-                                               decode_rd_as4(pnt + 2, &rd_as);
-                                       else if (type == RD_TYPE_IP)
-                                               decode_rd_ip(pnt + 2, &rd_ip);
-                                       if (use_json) {
-                                               if (type == RD_TYPE_AS
-                                                   || type == RD_TYPE_AS4)
-                                                       sprintf(rd_str, "%u:%d",
-                                                               rd_as.as,
-                                                               rd_as.val);
-                                               else if (type == RD_TYPE_IP)
-                                                       sprintf(rd_str, "%s:%d",
-                                                               inet_ntoa(
-                                                                       rd_ip.ip),
-                                                               rd_ip.val);
-                                               json_object_string_add(
-                                                       json_nroute,
-                                                       "rd",
-                                                       rd_str);
-
-                                       } else {
-                                               vty_out(vty,
-                                                       "Route Distinguisher: ");
-                                               if (type == RD_TYPE_AS)
-                                                       vty_out(vty,
-                                                               "as2 %u:%d",
-                                                               rd_as.as,
-                                                               rd_as.val);
-                                               else if (type == RD_TYPE_AS4)
-                                                       vty_out(vty,
-                                                               "as4 %u:%d",
-                                                               rd_as.as,
-                                                               rd_as.val);
-                                               else if (type == RD_TYPE_IP)
-                                                       vty_out(vty, "ip %s:%d",
-                                                               inet_ntoa(
-                                                                       rd_ip.ip),
-                                                               rd_ip.val);
-                                               vty_out(vty, "\n\n");
-                                       }
+                                       if (use_json)
+                                               json_nroute =
+                                                      json_object_new_object();
+                                       bgp_evpn_show_route_rd_header(vty, rn,
+                                               json_nroute, rd_str,
+                                               RD_ADDRSTRLEN);
                                        rd_header = 0;
                                }
+                               if (use_json && !json_array)
+                                       json_array = json_object_new_array();
 
                                if (option == SHOW_DISPLAY_TAGS)
                                        route_vty_out_tag(vty, &rm->p, pi,
@@ -1219,15 +1248,26 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
                        if (no_display)
                                output_count++;
 
-                       if (use_json) {
+                       if (use_json && json_array) {
+                               json_prefix_info = json_object_new_object();
+
+                               json_object_string_add(json_prefix_info,
+                                       "prefix", bgp_evpn_route2str(
+                                       (struct prefix_evpn *)&rm->p, buf,
+                                       BUFSIZ));
+
+                               json_object_int_add(json_prefix_info,
+                                       "prefixLen", rm->p.prefixlen);
+
                                json_object_object_add(json_prefix_info,
                                        "paths", json_array);
                                json_object_object_add(json_nroute, buf,
                                        json_prefix_info);
+                               json_array = NULL;
                        }
                }
 
-               if (use_json)
+               if (use_json && json_nroute)
                        json_object_object_add(json, rd_str, json_nroute);
        }
 
@@ -2604,10 +2644,8 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                prefix_rd2str((struct prefix_rd *)&rd_rn->p, rd_str,
                              sizeof(rd_str));
 
-               if (json) {
+               if (json)
                        json_rd = json_object_new_object();
-                       json_object_string_add(json_rd, "rd", rd_str);
-               }
 
                rd_header = 1;
 
@@ -2644,7 +2682,8 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                                /* RD header - per RD. */
                                if (rd_header) {
                                        bgp_evpn_show_route_rd_header(
-                                               vty, rd_rn, json);
+                                               vty, rd_rn, json_rd, rd_str,
+                                               RD_ADDRSTRLEN);
                                        rd_header = 0;
                                }
 
@@ -3636,6 +3675,139 @@ DEFUN (no_bgp_evpn_advertise_type5,
        return CMD_SUCCESS;
 }
 
+DEFPY (bgp_evpn_advertise_pip_ip_mac,
+       bgp_evpn_advertise_pip_ip_mac_cmd,
+       "[no$no] advertise-pip [ip <A.B.C.D> [mac <X:X:X:X:X:X|X:X:X:X:X:X/M>]]",
+       NO_STR
+       "evpn system primary IP\n"
+       IP_STR
+       "ip address\n"
+       MAC_STR MAC_STR MAC_STR)
+{
+       struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
+       struct bgp *bgp_evpn = NULL;
+
+       if (EVPN_ENABLED(bgp_vrf)) {
+               vty_out(vty,
+                       "This command is supported under L3VNI BGP EVPN VRF\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+       bgp_evpn = bgp_get_evpn();
+
+       if (!no) {
+               /* pip is already enabled */
+               if (argc == 1 && bgp_vrf->evpn_info->advertise_pip)
+                       return CMD_SUCCESS;
+
+               bgp_vrf->evpn_info->advertise_pip = true;
+               if (ip.s_addr != INADDR_ANY) {
+                       /* Already configured with same IP */
+                       if (IPV4_ADDR_SAME(&ip,
+                                       &bgp_vrf->evpn_info->pip_ip_static))
+                               return CMD_SUCCESS;
+
+                       bgp_vrf->evpn_info->pip_ip_static = ip;
+                       bgp_vrf->evpn_info->pip_ip = ip;
+               } else {
+                       bgp_vrf->evpn_info->pip_ip_static.s_addr
+                               = INADDR_ANY;
+                       /* default instance router-id assignemt */
+                       if (bgp_evpn)
+                               bgp_vrf->evpn_info->pip_ip =
+                                       bgp_evpn->router_id;
+               }
+               /* parse sys mac */
+               if (!is_zero_mac(&mac->eth_addr)) {
+                       /* Already configured with same MAC */
+                       if (memcmp(&bgp_vrf->evpn_info->pip_rmac_static,
+                                  &mac->eth_addr, ETH_ALEN) == 0)
+                               return CMD_SUCCESS;
+
+                       memcpy(&bgp_vrf->evpn_info->pip_rmac_static,
+                              &mac->eth_addr, ETH_ALEN);
+                       memcpy(&bgp_vrf->evpn_info->pip_rmac,
+                              &bgp_vrf->evpn_info->pip_rmac_static,
+                              ETH_ALEN);
+               } else {
+                       /* Copy zebra sys mac */
+                       if (!is_zero_mac(&bgp_vrf->evpn_info->pip_rmac_zebra))
+                               memcpy(&bgp_vrf->evpn_info->pip_rmac,
+                                      &bgp_vrf->evpn_info->pip_rmac_zebra,
+                                      ETH_ALEN);
+               }
+       } else {
+               if (argc == 2) {
+                       if (!bgp_vrf->evpn_info->advertise_pip)
+                               return CMD_SUCCESS;
+                       /* Disable PIP feature */
+                       bgp_vrf->evpn_info->advertise_pip = false;
+                       /* copy anycast mac */
+                       memcpy(&bgp_vrf->evpn_info->pip_rmac,
+                              &bgp_vrf->rmac, ETH_ALEN);
+               } else {
+                       /* remove MAC-IP option retain PIP knob. */
+                       if ((ip.s_addr != INADDR_ANY) &&
+                           !IPV4_ADDR_SAME(&ip,
+                                       &bgp_vrf->evpn_info->pip_ip_static)) {
+                               vty_out(vty,
+                                       "%% BGP EVPN PIP IP does not match\n");
+                               return CMD_WARNING_CONFIG_FAILED;
+                       }
+
+                       if (!is_zero_mac(&mac->eth_addr) &&
+                           memcmp(&bgp_vrf->evpn_info->pip_rmac_static,
+                                  &mac->eth_addr, ETH_ALEN) != 0) {
+                               vty_out(vty,
+                                       "%% BGP EVPN PIP MAC does not match\n");
+                               return CMD_WARNING_CONFIG_FAILED;
+                       }
+                       /* pip_rmac can carry vrr_rmac reset only if it matches
+                        * with static value.
+                        */
+                       if (memcmp(&bgp_vrf->evpn_info->pip_rmac,
+                                  &bgp_vrf->evpn_info->pip_rmac_static,
+                                  ETH_ALEN) == 0) {
+                               /* Copy zebra sys mac */
+                               if (!is_zero_mac(
+                                       &bgp_vrf->evpn_info->pip_rmac_zebra))
+                                       memcpy(&bgp_vrf->evpn_info->pip_rmac,
+                                       &bgp_vrf->evpn_info->pip_rmac_zebra,
+                                              ETH_ALEN);
+                               else {
+                                       /* copy anycast mac */
+                                       memcpy(&bgp_vrf->evpn_info->pip_rmac,
+                                              &bgp_vrf->rmac, ETH_ALEN);
+                               }
+                       }
+               }
+               /* reset user configured sys MAC */
+               memset(&bgp_vrf->evpn_info->pip_rmac_static, 0, ETH_ALEN);
+               /* reset user configured sys IP */
+               bgp_vrf->evpn_info->pip_ip_static.s_addr = INADDR_ANY;
+               /* Assign default PIP IP (bgp instance router-id) */
+               if (bgp_evpn)
+                       bgp_vrf->evpn_info->pip_ip = bgp_evpn->router_id;
+               else
+                       bgp_vrf->evpn_info->pip_ip.s_addr = INADDR_ANY;
+       }
+
+       if (is_evpn_enabled()) {
+               struct listnode *node = NULL;
+               struct bgpevpn *vpn = NULL;
+
+               update_advertise_vrf_routes(bgp_vrf);
+
+               /* Update (svi) type-2 routes */
+               for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) {
+                       if (!bgp_evpn_is_svi_macip_enabled(vpn))
+                               continue;
+                       update_routes_for_vni(bgp_evpn, vpn);
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
 /*
  * Display VNI information - for all or a specific VNI
  */
@@ -3687,6 +3859,9 @@ DEFUN(show_bgp_l2vpn_evpn_vni,
                                               bgp_evpn->advertise_gw_macip
                                                       ? "Enabled"
                                                       : "Disabled");
+                       json_object_string_add(json, "advertiseSviMacip",
+                                       bgp_evpn->evpn_info->advertise_svi_macip
+                                       ? "Enabled" : "Disabled");
                        json_object_string_add(json, "advertiseAllVnis",
                                               is_evpn_enabled() ? "Enabled"
                                                                 : "Disabled");
@@ -5366,6 +5541,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
                                safi_t safi)
 {
        char buf1[RD_ADDRSTRLEN];
+       char buf2[INET6_ADDRSTRLEN];
 
        if (bgp->vnihash) {
                struct list *vnilist = hash_to_list(bgp->vnihash);
@@ -5440,6 +5616,30 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
                       BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
                vty_out(vty, "  default-originate ipv6\n");
 
+       if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
+               if (!bgp->evpn_info->advertise_pip)
+                       vty_out(vty, "  no advertise-pip\n");
+               if (bgp->evpn_info->advertise_pip) {
+                       if (bgp->evpn_info->pip_ip_static.s_addr
+                           != INADDR_ANY) {
+                               vty_out(vty, "  advertise-pip ip %s",
+                                       inet_ntop(AF_INET,
+                                       &bgp->evpn_info->pip_ip_static,
+                                       buf2, INET_ADDRSTRLEN));
+                               if (!is_zero_mac(&(
+                                           bgp->evpn_info->pip_rmac_static))) {
+                                       char buf[ETHER_ADDR_STRLEN];
+
+                                       vty_out(vty, " mac %s",
+                                               prefix_mac2str(
+                                                       &bgp->evpn_info
+                                                                ->pip_rmac,
+                                                       buf, sizeof(buf)));
+                               }
+                               vty_out(vty, "\n");
+                       }
+               }
+       }
        if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
                vty_out(vty, "  rd %s\n",
                        prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1)));
@@ -5510,6 +5710,7 @@ void bgp_ethernetvpn_init(void)
        install_element(BGP_EVPN_NODE, &dup_addr_detection_auto_recovery_cmd);
        install_element(BGP_EVPN_NODE, &no_dup_addr_detection_cmd);
        install_element(BGP_EVPN_NODE, &bgp_evpn_flood_control_cmd);
+       install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_pip_ip_mac_cmd);
 
        /* test commands */
        install_element(BGP_EVPN_NODE, &test_adv_evpn_type4_route_cmd);