]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #4140 from ton31337/fix/do_not_send_notification_again_with_invali...
authorRuss White <russ@riw.us>
Thu, 25 Apr 2019 22:43:10 +0000 (18:43 -0400)
committerGitHub <noreply@github.com>
Thu, 25 Apr 2019 22:43:10 +0000 (18:43 -0400)
bgpd: Do not send UPDATE message with maximum-prefix

1  2 
bgpd/bgp_evpn.c
bgpd/bgp_route.c

diff --combined bgpd/bgp_evpn.c
index 5d191a787ccf1d6f353daff3518d0c290efa5ad1,b8f30af385c3f5b4a805ea08aede594457eb2b79..52aa923959a91cc9870799f2dfec29694b773d4c
@@@ -609,8 -609,7 +609,8 @@@ static int bgp_zebra_send_remote_macip(
   * Add (update) or delete remote VTEP from zebra.
   */
  static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
 -                                    struct prefix_evpn *p, int add)
 +                              struct prefix_evpn *p,
 +                              int flood_control, int add)
  {
        struct stream *s;
  
                        add ? "ADD" : "DEL", vpn->vni);
                return -1;
        }
 +      stream_putl(s, flood_control);
  
        stream_putw_at(s, 0, stream_get_endp(s));
  
@@@ -891,7 -889,6 +891,7 @@@ static int evpn_zebra_install(struct bg
  {
        int ret;
        uint8_t flags;
 +      int flood_control;
  
        if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
                flags = 0;
                        bgp, vpn, p, pi->attr->nexthop, 1, flags,
                        mac_mobility_seqnum(pi->attr));
        } else {
 -              ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1);
 +              switch (pi->attr->pmsi_tnl_type) {
 +              case PMSI_TNLTYPE_INGR_REPL:
 +                      flood_control = VXLAN_FLOOD_HEAD_END_REPL;
 +                      break;
 +
 +              case PMSI_TNLTYPE_PIM_SM:
 +                      flood_control = VXLAN_FLOOD_PIM_SM;
 +                      break;
 +
 +              default:
 +                      flood_control = VXLAN_FLOOD_DISABLED;
 +                      break;
 +              }
 +              ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, flood_control, 1);
        }
  
        return ret;
@@@ -936,8 -920,7 +936,8 @@@ static int evpn_zebra_uninstall(struct 
                ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
                                                  0, 0, 0);
        else
 -              ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 0);
 +              ret = bgp_zebra_send_remote_vtep(bgp, vpn, p,
 +                                      VXLAN_FLOOD_DISABLED, 0);
  
        return ret;
  }
@@@ -2237,24 -2220,6 +2237,24 @@@ static int delete_all_vni_routes(struc
        return 0;
  }
  
 +/* BUM traffic flood mode per-l2-vni */
 +static int bgp_evpn_vni_flood_mode_get(struct bgp *bgp,
 +                                      struct bgpevpn *vpn)
 +{
 +      /* if flooding has been globally disabled per-vni mode is
 +       * not relevant
 +       */
 +      if (bgp->vxlan_flood_ctrl == VXLAN_FLOOD_DISABLED)
 +              return VXLAN_FLOOD_DISABLED;
 +
 +      /* if mcast group ip has been specified we use a PIM-SM MDT */
 +      if (vpn->mcast_grp.s_addr != INADDR_ANY)
 +              return VXLAN_FLOOD_PIM_SM;
 +
 +      /* default is ingress replication */
 +      return VXLAN_FLOOD_HEAD_END_REPL;
 +}
 +
  /*
   * Update (and advertise) local routes for a VNI. Invoked upon the VNI
   * export RT getting modified or change to tunnel IP. Note that these
@@@ -2271,8 -2236,7 +2271,8 @@@ static int update_routes_for_vni(struc
         *
         * RT-3 only if doing head-end replication
         */
 -      if (bgp->vxlan_flood_ctrl == VXLAN_FLOOD_HEAD_END_REPL) {
 +      if (bgp_evpn_vni_flood_mode_get(bgp, vpn)
 +                              == VXLAN_FLOOD_HEAD_END_REPL) {
                build_evpn_type3_prefix(&p, vpn->originator_ip);
                ret = update_evpn_route(bgp, vpn, &p, 0, 0);
                if (ret)
@@@ -2332,26 -2296,6 +2332,26 @@@ static int delete_routes_for_vni(struc
        return delete_all_vni_routes(bgp, vpn);
  }
  
 +/*
 + * There is a flood mcast IP address change. Update the mcast-grp and
 + * remove the type-3 route if any. A new type-3 route will be generated
 + * post tunnel_ip update if the new flood mode is head-end-replication.
 + */
 +static int bgp_evpn_mcast_grp_change(struct bgp *bgp, struct bgpevpn *vpn,
 +              struct in_addr mcast_grp)
 +{
 +      struct prefix_evpn p;
 +
 +      vpn->mcast_grp = mcast_grp;
 +
 +      if (is_vni_live(vpn)) {
 +              build_evpn_type3_prefix(&p, vpn->originator_ip);
 +              delete_evpn_route(bgp, vpn, &p);
 +      }
 +
 +      return 0;
 +}
 +
  /*
   * There is a tunnel endpoint IP address change for this VNI, delete
   * prior type-3 route (if needed) and update.
@@@ -3594,8 -3538,7 +3594,8 @@@ static int update_advertise_vni_routes(
         *
         * RT-3 only if doing head-end replication
         */
 -      if (bgp->vxlan_flood_ctrl == VXLAN_FLOOD_HEAD_END_REPL) {
 +      if (bgp_evpn_vni_flood_mode_get(bgp, vpn)
 +                              == VXLAN_FLOOD_HEAD_END_REPL) {
                build_evpn_type3_prefix(&p, vpn->originator_ip);
                rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
                if (!rn) /* unexpected */
@@@ -3741,9 -3684,7 +3741,9 @@@ static void create_advertise_type3(stru
        struct bgp *bgp = data;
        struct prefix_evpn p;
  
 -      if (!vpn || !is_vni_live(vpn))
 +      if (!vpn || !is_vni_live(vpn) ||
 +              bgp_evpn_vni_flood_mode_get(bgp, vpn)
 +                                      != VXLAN_FLOOD_HEAD_END_REPL)
                return;
  
        build_evpn_type3_prefix(&p, vpn->originator_ip);
@@@ -3917,12 -3858,12 +3917,12 @@@ static int process_type3_route(struct p
         */
        if (attr &&
            (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
 -              if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL) {
 -                      flog_warn(
 -                              EC_BGP_EVPN_PMSI_PRESENT,
 -                              "%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
 -                              peer->bgp->vrf_id, peer->host,
 -                              attr->pmsi_tnl_type);
 +              if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL &&
 +                      attr->pmsi_tnl_type != PMSI_TNLTYPE_PIM_SM) {
 +                      flog_warn(EC_BGP_EVPN_PMSI_PRESENT,
 +                                "%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
 +                                peer->bgp->vrf_id, peer->host,
 +                                attr->pmsi_tnl_type);
                }
        }
  
@@@ -4921,7 -4862,7 +4921,7 @@@ int bgp_nlri_parse_evpn(struct peer *pe
                if (addpath_encoded) {
                        /* When packet overflow occurs return immediately. */
                        if (pnt + BGP_ADDPATH_ID_LEN > lim)
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
  
                        addpath_id = ntohl(*((uint32_t *)pnt));
                        pnt += BGP_ADDPATH_ID_LEN;
  
                /* All EVPN NLRI types start with type and length. */
                if (pnt + 2 > lim)
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_EVPN_MISSING_TYPE;
  
                rtype = *pnt++;
                psize = *pnt++;
  
                /* When packet overflow occur return immediately. */
                if (pnt + psize > lim)
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
  
                switch (rtype) {
                case BGP_EVPN_MAC_IP_ROUTE:
                                        EC_BGP_EVPN_FAIL,
                                        "%u:%s - Error in processing EVPN type-2 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE2_SIZE;
                        }
                        break;
  
                                        EC_BGP_PKT_PROCESS,
                                        "%u:%s - Error in processing EVPN type-3 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE3_SIZE;
                        }
                        break;
  
                                        EC_BGP_PKT_PROCESS,
                                        "%u:%s - Error in processing EVPN type-4 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE4_SIZE;
                        }
                        break;
  
                                        EC_BGP_PKT_PROCESS,
                                        "%u:%s - Error in processing EVPN type-5 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE5_SIZE;
                        }
                        break;
  
  
        /* Packet length consistency check. */
        if (pnt != lim)
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
  
-       return 0;
+       return BGP_NLRI_PARSE_OK;
  }
  
  /*
@@@ -5197,9 -5138,8 +5197,9 @@@ struct bgpevpn *bgp_evpn_lookup_vni(str
   * Create a new vpn - invoked upon configuration or zebra notification.
   */
  struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
 -                           struct in_addr originator_ip,
 -                           vrf_id_t tenant_vrf_id)
 +              struct in_addr originator_ip,
 +              vrf_id_t tenant_vrf_id,
 +              struct in_addr mcast_grp)
  {
        struct bgpevpn *vpn;
  
        vpn->vni = vni;
        vpn->originator_ip = originator_ip;
        vpn->tenant_vrf_id = tenant_vrf_id;
 +      vpn->mcast_grp = mcast_grp;
  
        /* Initialize route-target import and export lists */
        vpn->import_rtl = list_new();
@@@ -5711,10 -5650,7 +5711,10 @@@ int bgp_evpn_local_vni_del(struct bgp *
   * about are for the local-tunnel-ip and the (tenant) VRF.
   */
  int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
 -                         struct in_addr originator_ip, vrf_id_t tenant_vrf_id)
 +                         struct in_addr originator_ip,
 +                         vrf_id_t tenant_vrf_id,
 +                         struct in_addr mcast_grp)
 +
  {
        struct bgpevpn *vpn;
        struct prefix_evpn p;
  
                if (is_vni_live(vpn)
                    && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)
 +                  && IPV4_ADDR_SAME(&vpn->mcast_grp, &mcast_grp)
                    && vpn->tenant_vrf_id == tenant_vrf_id)
                        /* Probably some other param has changed that we don't
                         * care about. */
                        return 0;
  
 +              bgp_evpn_mcast_grp_change(bgp, vpn, mcast_grp);
 +
                /* Update tenant_vrf_id if it has changed. */
                if (vpn->tenant_vrf_id != tenant_vrf_id) {
                        bgpevpn_unlink_from_l3vni(vpn);
  
        /* Create or update as appropriate. */
        if (!vpn) {
 -              vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id);
 +              vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id,
 +                              mcast_grp);
                if (!vpn) {
                        flog_err(
                                EC_BGP_VNI,
         *
         * RT-3 only if doing head-end replication
         */
 -      if (bgp->vxlan_flood_ctrl == VXLAN_FLOOD_HEAD_END_REPL) {
 +      if (bgp_evpn_vni_flood_mode_get(bgp, vpn)
 +                      == VXLAN_FLOOD_HEAD_END_REPL) {
                build_evpn_type3_prefix(&p, vpn->originator_ip);
                if (update_evpn_route(bgp, vpn, &p, 0, 0)) {
                        flog_err(EC_BGP_EVPN_ROUTE_CREATE,
diff --combined bgpd/bgp_route.c
index 36d1369eb086e31d014b5b74093947d9c7f9514c,f8b8cfc08c7adff900d0b6d3ee6ece29ed360cda..063cc24dc1bd69918e6397b14c9ba8d97a4161c7
@@@ -4218,13 -4218,6 +4218,13 @@@ static void bgp_cleanup_table(struct bg
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
                for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
                        next = pi->next;
 +
 +                      /* Unimport EVPN routes from VRFs */
 +                      if (safi == SAFI_EVPN)
 +                              bgp_evpn_unimport_route(bgp, AFI_L2VPN,
 +                                                      SAFI_EVPN,
 +                                                      &rn->p, pi);
 +
                        if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
                            && pi->type == ZEBRA_ROUTE_BGP
                            && (pi->sub_type == BGP_ROUTE_NORMAL
@@@ -4340,7 -4333,7 +4340,7 @@@ int bgp_nlri_parse_ip(struct peer *peer
  
                        /* When packet overflow occurs return immediately. */
                        if (pnt + BGP_ADDPATH_ID_LEN > lim)
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
  
                        addpath_id = ntohl(*((uint32_t *)pnt));
                        pnt += BGP_ADDPATH_ID_LEN;
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
                                peer->host, p.prefixlen, packet->afi);
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
                }
  
                /* Packet size overflow check. */
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d overflows packet)",
                                peer->host, p.prefixlen);
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
                }
  
                /* Defensive coding, double-check the psize fits in a struct
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
                                peer->host, p.prefixlen, sizeof(p.u));
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
                }
  
                /* Fetch prefix from NLRI packet. */
                                           BGP_ROUTE_NORMAL, NULL, NULL, 0,
                                           NULL);
  
-               /* Address family configuration mismatch or maximum-prefix count
-                  overflow. */
+               /* Do not send BGP notification twice when maximum-prefix count
+                * overflow. */
+               if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
+                       return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
+               /* Address family configuration mismatch. */
                if (ret < 0)
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
        }
  
        /* Packet length consistency check. */
                        EC_BGP_UPDATE_RCV,
                        "%s [Error] Update packet error (prefix length mismatch with total length)",
                        peer->host);
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
        }
  
-       return 0;
+       return BGP_NLRI_PARSE_OK;
  }
  
  static struct bgp_static *bgp_static_new(void)
@@@ -9934,7 -9931,7 +9938,7 @@@ DEFUN (show_ip_bgp_regexp
         BGP_AFI_HELP_STR
         BGP_SAFI_WITH_LABEL_HELP_STR
         "Display routes matching the AS path regular expression\n"
 -       "A regular-expression to match the BGP AS paths\n")
 +       "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
  {
        afi_t afi = AFI_IP6;
        safi_t safi = SAFI_UNICAST;
@@@ -9992,12 -9989,6 +9996,12 @@@ static int bgp_show_regexp(struct vty *
        regex_t *regex;
        int rc;
  
 +      if (!config_bgp_aspath_validate(regstr)) {
 +              vty_out(vty, "Invalid character in as-path access-list %s\n",
 +                      regstr);
 +              return CMD_WARNING_CONFIG_FAILED;
 +      }
 +
        regex = bgp_regcomp(regstr);
        if (!regex) {
                vty_out(vty, "Can't compile regexp %s\n", regstr);