]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Check if route-map really exists before applying to the peer
authorDonatas Abraitis <donatas.abraitis@gmail.com>
Fri, 14 Sep 2018 08:56:46 +0000 (11:56 +0300)
committerDonatas Abraitis <donatas.abraitis@gmail.com>
Thu, 11 Oct 2018 07:56:12 +0000 (10:56 +0300)
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgp_zebra.h
bgpd/bgpd.c
bgpd/bgpd.h
lib/routemap.c
lib/routemap.h

index 58f23fd2f4338d16f1c12f07def034bfa32464d9..a7d31f5604d20ed50e4e7565010b1453aa4852f3 100644 (file)
@@ -4767,14 +4767,17 @@ static int peer_default_originate_set_vty(struct vty *vty, const char *peer_str,
 {
        int ret;
        struct peer *peer;
+       struct route_map *route_map;
 
        peer = peer_and_group_lookup_vty(vty, peer_str);
        if (!peer)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (set)
-               ret = peer_default_originate_set(peer, afi, safi, rmap);
-       else
+       if (set) {
+               route_map = route_map_lookup_warn_noexist(vty, rmap);
+               ret = peer_default_originate_set(peer, afi, safi,
+                                                rmap, route_map);
+       } else
                ret = peer_default_originate_unset(peer, afi, safi);
 
        return bgp_vty_return(vty, ret);
@@ -5593,6 +5596,7 @@ static int peer_route_map_set_vty(struct vty *vty, const char *ip_str,
        int ret;
        struct peer *peer;
        int direct = RMAP_IN;
+       struct route_map *route_map;
 
        peer = peer_and_group_lookup_vty(vty, ip_str);
        if (!peer)
@@ -5604,7 +5608,8 @@ static int peer_route_map_set_vty(struct vty *vty, const char *ip_str,
        else if (strncmp(direct_str, "o", 1) == 0)
                direct = RMAP_OUT;
 
-       ret = peer_route_map_set(peer, afi, safi, direct, name_str);
+       route_map = route_map_lookup_warn_noexist(vty, name_str);
+       ret = peer_route_map_set(peer, afi, safi, direct, name_str, route_map);
 
        return bgp_vty_return(vty, ret);
 }
@@ -5691,12 +5696,14 @@ static int peer_unsuppress_map_set_vty(struct vty *vty, const char *ip_str,
 {
        int ret;
        struct peer *peer;
+       struct route_map *route_map;
 
        peer = peer_and_group_lookup_vty(vty, ip_str);
        if (!peer)
                return CMD_WARNING_CONFIG_FAILED;
 
-       ret = peer_unsuppress_map_set(peer, afi, safi, name_str);
+       route_map = route_map_lookup_warn_noexist(vty, name_str);
+       ret = peer_unsuppress_map_set(peer, afi, safi, name_str, route_map);
 
        return bgp_vty_return(vty, ret);
 }
@@ -6646,7 +6653,7 @@ DEFPY (af_route_map_vpn_imexport,
                        bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP(
                                                                      MTYPE_ROUTE_MAP_NAME, rmap_str);
                        bgp->vpn_policy[afi].rmap[dir] =
-                               route_map_lookup_by_name(rmap_str);
+                               route_map_lookup_warn_noexist(vty, rmap_str);
                        if (!bgp->vpn_policy[afi].rmap[dir])
                                return CMD_SUCCESS;
                } else {
@@ -6719,7 +6726,7 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd,
                bgp->vpn_policy[afi].rmap_name[dir] =
                        XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
                bgp->vpn_policy[afi].rmap[dir] =
-                       route_map_lookup_by_name(rmap_str);
+                       route_map_lookup_warn_noexist(vty, rmap_str);
                if (!bgp->vpn_policy[afi].rmap[dir])
                        return CMD_SUCCESS;
        } else {
@@ -11641,6 +11648,8 @@ DEFUN (bgp_redistribute_ipv4_rmap,
        int type;
        struct bgp_redist *red;
        bool changed;
+       struct route_map *route_map = route_map_lookup_warn_noexist(
+               vty, argv[idx_word]->arg);
 
        type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
        if (type < 0) {
@@ -11649,7 +11658,8 @@ DEFUN (bgp_redistribute_ipv4_rmap,
        }
 
        red = bgp_redist_add(bgp, AFI_IP, type, 0);
-       changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed =
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed);
 }
 
@@ -11713,6 +11723,8 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
        uint32_t metric;
        struct bgp_redist *red;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
        if (type < 0) {
@@ -11722,7 +11734,8 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
        metric = strtoul(argv[idx_number]->arg, NULL, 10);
 
        red = bgp_redist_add(bgp, AFI_IP, type, 0);
-       changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed =
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
        return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed);
 }
@@ -11756,6 +11769,8 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
        uint32_t metric;
        struct bgp_redist *red;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
        if (type < 0) {
@@ -11766,7 +11781,8 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
 
        red = bgp_redist_add(bgp, AFI_IP, type, 0);
        changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
-       changed |= bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed |=
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed);
 }
 
@@ -11831,6 +11847,8 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap,
        unsigned short instance;
        int protocol;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
                protocol = ZEBRA_ROUTE_OSPF;
@@ -11839,7 +11857,8 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap,
 
        instance = strtoul(argv[idx_number]->arg, NULL, 10);
        red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
-       changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed =
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
 }
 
@@ -11919,6 +11938,8 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
        unsigned short instance;
        int protocol;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
                protocol = ZEBRA_ROUTE_OSPF;
@@ -11929,7 +11950,8 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
        metric = strtoul(argv[idx_number_2]->arg, NULL, 10);
 
        red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
-       changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed =
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol,
                                                metric);
        return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
@@ -11970,6 +11992,8 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
        unsigned short instance;
        int protocol;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
                protocol = ZEBRA_ROUTE_OSPF;
@@ -11982,7 +12006,8 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
        red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
        changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol,
                                                metric);
-       changed |= bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed |=
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
 }
 
@@ -12108,6 +12133,8 @@ DEFUN (bgp_redistribute_ipv6_rmap,
        int type;
        struct bgp_redist *red;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
        if (type < 0) {
@@ -12116,7 +12143,8 @@ DEFUN (bgp_redistribute_ipv6_rmap,
        }
 
        red = bgp_redist_add(bgp, AFI_IP6, type, 0);
-       changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed =
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
 }
 
@@ -12166,6 +12194,8 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
        uint32_t metric;
        struct bgp_redist *red;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
        if (type < 0) {
@@ -12175,7 +12205,8 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
        metric = strtoul(argv[idx_number]->arg, NULL, 10);
 
        red = bgp_redist_add(bgp, AFI_IP6, type, 0);
-       changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed =
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP6, type,
                                                metric);
        return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
@@ -12199,6 +12230,8 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
        uint32_t metric;
        struct bgp_redist *red;
        bool changed;
+       struct route_map *route_map =
+               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
 
        type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
        if (type < 0) {
@@ -12210,7 +12243,8 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
        red = bgp_redist_add(bgp, AFI_IP6, type, 0);
        changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, SAFI_UNICAST,
                                                metric);
-       changed |= bgp_redistribute_rmap_set(red, argv[idx_word]->arg);
+       changed |=
+               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
        return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
 }
 
index 5a5c7c9861635036817959a06faa225db7bbfc63..e92cc0a2580d06eb341191b9fb2e4a4ce48ede2f 100644 (file)
@@ -1662,7 +1662,8 @@ int bgp_redistribute_resend(struct bgp *bgp, afi_t afi, int type,
 }
 
 /* Redistribute with route-map specification.  */
-int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name)
+int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name,
+                             struct route_map *route_map)
 {
        if (red->rmap.name && (strcmp(red->rmap.name, name) == 0))
                return 0;
@@ -1670,7 +1671,7 @@ int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name)
        if (red->rmap.name)
                XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
        red->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
-       red->rmap.map = route_map_lookup_by_name(name);
+       red->rmap.map = route_map;
 
        return 1;
 }
index 0223c423df770153a85ae31c33104230eac525b9..837bae14a7625d736471f76e530450303d112f6a 100644 (file)
@@ -55,7 +55,8 @@ extern struct bgp_redist *bgp_redist_add(struct bgp *, afi_t, uint8_t,
 extern int bgp_redistribute_set(struct bgp *, afi_t, int, unsigned short,
                                bool changed);
 extern int bgp_redistribute_resend(struct bgp *, afi_t, int, unsigned short);
-extern int bgp_redistribute_rmap_set(struct bgp_redist *, const char *);
+extern int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name,
+                                    struct route_map *route_map);
 extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *, afi_t,
                                       int, uint32_t);
 extern int bgp_redistribute_unset(struct bgp *, afi_t, int, unsigned short);
index 0300485e9110f6bbc97a67f0b5c24d9d8e6dc419..c77870f7c7321d3149fb3c48a24aa85ae9d48be1 100644 (file)
@@ -4485,7 +4485,7 @@ int peer_update_source_unset(struct peer *peer)
 }
 
 int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
-                              const char *rmap)
+                              const char *rmap, struct route_map *route_map)
 {
        struct peer *member;
        struct listnode *node, *nnode;
@@ -4501,8 +4501,7 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
 
                        peer->default_rmap[afi][safi].name =
                                XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
-                       peer->default_rmap[afi][safi].map =
-                               route_map_lookup_by_name(rmap);
+                       peer->default_rmap[afi][safi].map = route_map;
                }
        } else if (!rmap) {
                if (peer->default_rmap[afi][safi].name)
@@ -4546,8 +4545,7 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
 
                        member->default_rmap[afi][safi].name =
                                XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
-                       member->default_rmap[afi][safi].map =
-                               route_map_lookup_by_name(rmap);
+                       member->default_rmap[afi][safi].map = route_map;
                }
 
                /* Update peer route announcements. */
@@ -6012,7 +6010,7 @@ static void peer_aslist_del(const char *aslist_name)
 
 
 int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
-                      const char *name)
+                      const char *name, struct route_map *route_map)
 {
        struct peer *member;
        struct bgp_filter *filter;
@@ -6026,7 +6024,7 @@ int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
        if (filter->map[direct].name)
                XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
        filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
-       filter->map[direct].map = route_map_lookup_by_name(name);
+       filter->map[direct].map = route_map;
 
        /* Check if handling a regular peer. */
        if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
@@ -6055,7 +6053,7 @@ int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
                if (filter->map[direct].name)
                        XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
                filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
-               filter->map[direct].map = route_map_lookup_by_name(name);
+               filter->map[direct].map = route_map;
 
                /* Process peer route updates. */
                peer_on_policy_change(member, afi, safi,
@@ -6130,7 +6128,7 @@ int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
 
 /* Set unsuppress-map to the peer. */
 int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
-                           const char *name)
+                           const char *name, struct route_map *route_map)
 {
        struct peer *member;
        struct bgp_filter *filter;
@@ -6141,7 +6139,7 @@ int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
        if (filter->usmap.name)
                XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
        filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
-       filter->usmap.map = route_map_lookup_by_name(name);
+       filter->usmap.map = route_map;
 
        /* Check if handling a regular peer. */
        if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
@@ -6169,7 +6167,7 @@ int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
                if (filter->usmap.name)
                        XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
                filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
-               filter->usmap.map = route_map_lookup_by_name(name);
+               filter->usmap.map = route_map;
 
                /* Process peer route updates. */
                peer_on_policy_change(member, afi, safi, 1);
index 861435c036cb08eed7a5cbfe4c8e58fdb7fb0205..2ca9e9b8cb6ab67a8324a66b387255a9a84a22d7 100644 (file)
@@ -1605,8 +1605,9 @@ extern int peer_update_source_if_set(struct peer *, const char *);
 extern int peer_update_source_addr_set(struct peer *, const union sockunion *);
 extern int peer_update_source_unset(struct peer *);
 
-extern int peer_default_originate_set(struct peer *, afi_t, safi_t,
-                                     const char *);
+extern int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
+                                     const char *rmap,
+                                     struct route_map *route_map);
 extern int peer_default_originate_unset(struct peer *, afi_t, safi_t);
 
 extern int peer_port_set(struct peer *, uint16_t);
@@ -1644,10 +1645,13 @@ extern int peer_prefix_list_unset(struct peer *, afi_t, safi_t, int);
 extern int peer_aslist_set(struct peer *, afi_t, safi_t, int, const char *);
 extern int peer_aslist_unset(struct peer *, afi_t, safi_t, int);
 
-extern int peer_route_map_set(struct peer *, afi_t, safi_t, int, const char *);
+extern int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int,
+                             const char *name, struct route_map *route_map);
 extern int peer_route_map_unset(struct peer *, afi_t, safi_t, int);
 
-extern int peer_unsuppress_map_set(struct peer *, afi_t, safi_t, const char *);
+extern int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
+                                  const char *name,
+                                  struct route_map *route_map);
 
 extern int peer_password_set(struct peer *, const char *);
 extern int peer_password_unset(struct peer *);
index bc45cd51d0bffb47c5220cd8e3278cd9ef1ddee7..3a20ed5cdaea91e83096de38c137b339a38123ff 100644 (file)
@@ -811,6 +811,18 @@ struct route_map *route_map_lookup_by_name(const char *name)
        return map;
 }
 
+/* Simple helper to warn if route-map does not exist. */
+struct route_map *route_map_lookup_warn_noexist(struct vty *vty, const char *name)
+{
+       struct route_map *route_map = route_map_lookup_by_name(name);
+
+       if (!route_map)
+               if (vty_shell_serv(vty))
+                       vty_out(vty, "The route-map '%s' does not exist.\n", name);
+
+       return route_map;
+}
+
 int route_map_mark_updated(const char *name)
 {
        struct route_map *map;
index 481b8c4a9a34091b44b55931c8b0953671709aec..463aa91725a98b64b10a7516c9a5320fb641af7c 100644 (file)
@@ -220,6 +220,9 @@ extern void route_map_install_set(struct route_map_rule_cmd *cmd);
 /* Lookup route map by name. */
 extern struct route_map *route_map_lookup_by_name(const char *name);
 
+/* Simple helper to warn if route-map does not exist. */
+struct route_map *route_map_lookup_warn_noexist(struct vty *vty, const char *name);
+
 /* Apply route map to the object. */
 extern route_map_result_t route_map_apply(struct route_map *map,
                                          const struct prefix *prefix,