diff options
| -rw-r--r-- | bgpd/bgp_aspath.c | 2 | ||||
| -rw-r--r-- | doc/Building_FRR_on_Ubuntu1604.md | 6 | ||||
| -rw-r--r-- | doc/bgpd.texi | 99 | ||||
| -rw-r--r-- | lib/thread.c | 2 | ||||
| -rwxr-xr-x | tools/frr-reload.py | 27 | ||||
| -rw-r--r-- | zebra/interface.c | 4 | ||||
| -rw-r--r-- | zebra/redistribute.c | 12 | ||||
| -rw-r--r-- | zebra/zebra_mpls.c | 11 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 52 | ||||
| -rw-r--r-- | zebra/zebra_snmp.c | 15 | ||||
| -rw-r--r-- | zebra/zebra_vrf.c | 5 | ||||
| -rw-r--r-- | zebra/zserv.c | 2 |
12 files changed, 189 insertions, 48 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 2ce52d92a5..2b776d2182 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -892,7 +892,7 @@ size_t aspath_put(struct stream *s, struct aspath *as, int use32bit) assegment_data_put(s, seg->as, AS_SEGMENT_MAX, use32bit); written += AS_SEGMENT_MAX; - bytes += ASSEGMENT_SIZE(written, use32bit); + bytes += ASSEGMENT_SIZE(AS_SEGMENT_MAX, use32bit); } /* write the final segment, probably is also the first diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/Building_FRR_on_Ubuntu1604.md index a178f9a160..b33fb60253 100644 --- a/doc/Building_FRR_on_Ubuntu1604.md +++ b/doc/Building_FRR_on_Ubuntu1604.md @@ -55,7 +55,7 @@ an example.) --enable-logfile-mask=0640 \ --enable-rtadv \ --enable-fpm \ - --enable-systemd=yes \ + --enable-systemd=yes \ --with-pkg-git-version \ --with-pkg-extra-version=-MyOwnFRRVersion make @@ -78,7 +78,7 @@ an example.) sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf -### Enable IP & IPv6 forwarding +### Enable IPv4 & IPv6 forwarding Edit `/etc/sysctl.conf` and uncomment the following values (ignore the other settings) @@ -135,7 +135,7 @@ For example. ripngd=yes isisd=yes -### Enable the systemd serivce +### Enable the systemd service - systemctl enable frr ### Start the systemd service diff --git a/doc/bgpd.texi b/doc/bgpd.texi index 8e0da12949..1703617dc4 100644 --- a/doc/bgpd.texi +++ b/doc/bgpd.texi @@ -28,6 +28,7 @@ BGP-4. * Autonomous System:: * BGP Communities Attribute:: * BGP Extended Communities Attribute:: +* BGP Large Communities Attribute:: * Displaying BGP routes:: * Capability Negotiation:: * Route Reflector:: @@ -1372,6 +1373,104 @@ This command set Site of Origin value. @end deffn @c ----------------------------------------------------------------------- +@node BGP Large Communities Attribute +@section BGP Large Communities Attribute + +The BGP Large Communities attribute was introduced in Feb 2017 with +@cite{RFC8092, BGP Large Communities Attribute}. + +The BGP Large Communities Attribute is similar to the BGP Communities +Attribute except that it has 3 components instead of two and each of +which are 4 octets in length. Large Communities bring additional +functionality and convenience over traditional communities, specifically +the fact that the @code{GLOBAL} part below is now 4 octets wide allowing +AS4 operators seamless use. + +@table @code +@item GLOBAL:LOCAL1:LOCAL2 +This is the format to define Large Community values. Referencing +@cite{RFC8195, Use of BGP Large Communities} the values are commonly +referred to as follows. +The @code{GLOBAL} part is a 4 octet Global Administrator field, common +use of this field is the operators AS number. +The @code{LOCAL1} part is a 4 octet Local Data Part 1 subfield referred +to as a function. +The @code{LOCAL2} part is a 4 octet Local Data Part 2 field and referred +to as the parameter subfield. @code{65551:1:10} represents AS 65551 +function 1 and parameter 10. +The referenced RFC above gives some guidelines on recommended usage. +@end table + +@menu +* BGP Large Community Lists:: +* BGP Large Communities in Route Map:: +@end menu + +@node BGP Large Community Lists +@subsection BGP Large Community Lists + +Two types of large community lists are supported, namely @code{standard} and +@code{expanded}. + +@deffn Command {ip large-community-list standard @var{name} @{permit|deny@} @var{large-community}} {} +This command defines a new standard large-community-list. +@var{large-community} is the Large Community value. We +can add multiple large communities under same name. In that case +the match will happen in the user defined order. Once the large-community-list +matches the Large Communities attribute in BGP updates it will return +permit or deny based upon the large-community-list definition. When +there is no matched entry, a deny will be returned. When @var{large-community} +is empty it matches any routes. +@end deffn + +@deffn Command {ip large-community-list expanded @var{name} @{permit|deny@} @var{line}} {} +This command defines a new expanded large-community-list. Where @var{line} is +a string matching expression, it will be compared to the entire Large Communities +attribute as a string, with each large-community in order from lowest to highest. +@var{line} can also be a regular expression which matches this Large +Community attribute. +@end deffn + +@deffn Command {no ip large-community-list @var{name}} {} +@deffnx Command {no ip large-community-list standard @var{name}} {} +@deffnx Command {no ip large-community-list expanded @var{name}} {} +These commands delete Large Community lists specified by +@var{name}. All Large Community lists share a single namespace. +This means Large Community lists can be removed by simply specifying the name. +@end deffn + +@deffn {Command} {show ip large-community-list} {} +@deffnx {Command} {show ip large-community-list @var{name}} {} +This command display current large-community-list information. When +@var{name} is specified the community list information is shown. +@end deffn + +@deffn {Command} {show ip bgp large-community-info} {} +This command displays the current large communities in use. +@end deffn + +@node BGP Large Communities in Route Map +@subsection BGP Large Communities in Route Map + +@deffn {Route Map} {match large-community @var{line}} {} +Where @var{line} can be a simple string to match, or a regular expression. +It is very important to note that this match occurs on the entire +large-community string as a whole, where each large-community is ordered +from lowest to highest. +@end deffn + +@deffn {Route Map} {set large-community @var{large-community}} {} +@deffnx {Route Map} {set large-community @var{large-community} @var{large-community}} {} +@deffnx {Route Map} {set large-community @var{large-community} additive} {} +These commands are used for setting large-community values. The first +command will overwrite any large-communities currently present. +The second specifies two large-communities, which overwrites the current +large-community list. The third will add a large-community value without +overwriting other values. Multiple large-community values can be specified. +@end deffn + +@c ----------------------------------------------------------------------- + @node Displaying BGP routes @section Displaying BGP Routes diff --git a/lib/thread.c b/lib/thread.c index 0ce38dd340..d8be32e2bd 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -575,6 +575,8 @@ void thread_master_free(struct thread_master *m) hash_free(m->cpu_record); m->cpu_record = NULL; + if (m->name) + XFREE(MTYPE_THREAD_MASTER, m->name); XFREE(MTYPE_THREAD_MASTER, m->handler.pfds); XFREE(MTYPE_THREAD_MASTER, m->handler.copy); XFREE(MTYPE_THREAD_MASTER, m); diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 8556f0b46e..8f34b4cb3f 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -320,6 +320,17 @@ end exit-address-family ! end + address-family evpn + neighbor LEAF activate + advertise-all-vni + vni 10100 + rd 65000:10100 + route-target import 10.1.1.1:10100 + route-target export 10.1.1.1:10100 + exit-vni + exit-address-family +! +end router ospf ospf router-id 10.0.0.1 log-adjacency-changes detail @@ -398,7 +409,7 @@ end ctx_keys = [] current_context_lines = [] - elif line == "exit-address-family" or line == "exit": + elif line == "exit-address-family" or line == "exit" or line == "exit-vni": # if this exit is for address-family ipv4 unicast, ignore the pop if main_ctx_key: self.save_contexts(ctx_keys, current_context_lines) @@ -419,6 +430,17 @@ end new_ctx = False log.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys) + elif "vni " in line: + main_ctx_key = [] + + # Save old context first + self.save_contexts(ctx_keys, current_context_lines) + current_context_lines = [] + main_ctx_key = copy.deepcopy(ctx_keys) + log.debug('LINE %-50s: entering sub-context, append to ctx_keys', line) + + ctx_keys.append(line) + elif "address-family " in line: main_ctx_key = [] @@ -874,6 +896,9 @@ def compare_context_objects(newconf, running): elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys): lines_to_del.append((running_ctx_keys, None)) + elif running_ctx_keys and not any("vni" in key for key in running_ctx_keys): + lines_to_del.append((running_ctx_keys, None)) + # Global context else: for line in running_ctx.lines: diff --git a/zebra/interface.c b/zebra/interface.c index 5d02259159..358f940c52 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -2850,8 +2850,8 @@ static int if_config_write(struct vty *vty) if (ifp->vrf_id == VRF_DEFAULT) vty_frame(vty, "interface %s\n", ifp->name); else - vty_out(vty, "interface %s vrf %s\n", ifp->name, - vrf->name); + vty_frame(vty, "interface %s vrf %s\n", ifp->name, + vrf->name); if (if_data) { if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index ce86b6c1e3..93bfc0c031 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -84,11 +84,13 @@ static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id) if (!rn) continue; - RNODE_FOREACH_RE(rn, newre) - if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED) - && newre->distance != DISTANCE_INFINITY) - zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD, - client, &rn->p, NULL, newre); + RNODE_FOREACH_RE(rn, newre) { + if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED) + && newre->distance != DISTANCE_INFINITY) + zsend_redistribute_route( + ZEBRA_REDISTRIBUTE_ROUTE_ADD, + client, &rn->p, NULL, newre); + } route_unlock_node(rn); } diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 273945778a..e3ce414127 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -2392,15 +2392,20 @@ void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi) for (rn = route_top(table); rn; rn = route_next(rn)) { update = 0; - RNODE_FOREACH_RE(rn, re) - for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) - if (nexthop->nh_label_type == ZEBRA_LSP_LDP) { + RNODE_FOREACH_RE(rn, re) { + for (nexthop = re->nexthop; + nexthop; + nexthop = nexthop->next) { + if (nexthop->nh_label_type != ZEBRA_LSP_LDP) + continue; + nexthop_del_labels(nexthop); SET_FLAG(re->status, ROUTE_ENTRY_CHANGED); SET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED); update = 1; } + } if (update) rib_queue_add(rn); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index c4c80b156b..376425329b 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1118,7 +1118,6 @@ static int rib_can_delete_dest(rib_dest_t *dest) int rib_gc_dest(struct route_node *rn) { rib_dest_t *dest; - struct zebra_vrf *zvrf; dest = rib_dest_from_rnode(rn); if (!dest) @@ -1127,9 +1126,12 @@ int rib_gc_dest(struct route_node *rn) if (!rib_can_delete_dest(dest)) return 0; - zvrf = rib_dest_vrf(dest); - if (IS_ZEBRA_DEBUG_RIB) + if (IS_ZEBRA_DEBUG_RIB) { + struct zebra_vrf *zvrf; + + zvrf = rib_dest_vrf(dest); rnode_debug(rn, zvrf_id(zvrf), "removing dest from table"); + } dest->rnode = NULL; XFREE(MTYPE_RIB_DEST, dest); @@ -2551,27 +2553,29 @@ static void rib_update_table(struct route_table *table, */ RNODE_FOREACH_RE_SAFE(rn, re, next) { - if (re->type == ZEBRA_ROUTE_OSPF - || re->type == ZEBRA_ROUTE_OSPF6 - || re->type == ZEBRA_ROUTE_BGP) - continue; /* protocol will handle. */ - else if (re->type == ZEBRA_ROUTE_STATIC) { - struct nexthop *nh; - for (nh = re->nexthop; nh; - nh = nh->next) - if (!(nh->type - == NEXTHOP_TYPE_IPV4 - || nh->type - == NEXTHOP_TYPE_IPV6)) - break; - - /* If we only have nexthops to a - * gateway, NHT will - * take care. - */ - if (nh) - rib_queue_add(rn); - } else + struct nexthop *nh; + + if (re->type != ZEBRA_ROUTE_SYSTEM && + re->type != ZEBRA_ROUTE_KERNEL && + re->type != ZEBRA_ROUTE_CONNECT && + re->type != ZEBRA_ROUTE_STATIC) + continue; + + if (re->type != ZEBRA_ROUTE_STATIC) { + rib_queue_add(rn); + continue; + } + + for (nh = re->nexthop; nh; nh = nh->next) + if (!(nh->type == NEXTHOP_TYPE_IPV4 + || nh->type == NEXTHOP_TYPE_IPV6)) + break; + + /* If we only have nexthops to a + * gateway, NHT will + * take care. + */ + if (nh) rib_queue_add(rn); } break; diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 4d6ba566ca..9ac24c53ed 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -155,8 +155,9 @@ static u_char *ipFwNumber(struct variable *v, oid objid[], size_t *objid_len, /* Return number of routing entries. */ result = 0; for (rn = route_top(table); rn; rn = route_next(rn)) - RNODE_FOREACH_RE(rn, re) - result++; + RNODE_FOREACH_RE(rn, re) { + result++; + } return (u_char *)&result; } @@ -182,8 +183,9 @@ static u_char *ipCidrNumber(struct variable *v, oid objid[], size_t *objid_len, /* Return number of routing entries. */ result = 0; for (rn = route_top(table); rn; rn = route_next(rn)) - RNODE_FOREACH_RE(rn, re) - result++; + RNODE_FOREACH_RE(rn, re) { + result++; + } return (u_char *)&result; } @@ -388,8 +390,9 @@ static void get_fwtable_route_node(struct variable *v, oid objid[], /* Check destination first */ if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0) - RNODE_FOREACH_RE(np2, re2) - check_replace(np2, re2, np, re); + RNODE_FOREACH_RE(np2, re2) { + check_replace(np2, re2, np, re); + } if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0) { /* have to look at each re individually */ diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 0a26ac6ad7..62c7d020bc 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -290,8 +290,9 @@ static void zebra_rtable_node_cleanup(struct route_table *table, { struct route_entry *re, *next; - RNODE_FOREACH_RE_SAFE(node, re, next) - rib_unlink(node, re); + RNODE_FOREACH_RE_SAFE(node, re, next) { + rib_unlink(node, re); + } if (node->info) XFREE(MTYPE_RIB_DEST, node->info); diff --git a/zebra/zserv.c b/zebra/zserv.c index ef289f3960..61a75e156c 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -601,7 +601,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, int count = 0; memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = re->vrf_id; api.type = re->type; api.instance = re->instance; api.flags = re->flags; |
