merge with upstream

This commit is contained in:
tmartiro 2017-07-17 17:23:20 +03:00
commit a8a4fa8954
739 changed files with 269781 additions and 267777 deletions

25
.clang-format Normal file
View File

@ -0,0 +1,25 @@
---
BasedOnStyle: LLVM
Language: Cpp
IndentWidth: 8
UseTab: Always
BreakBeforeBraces: Linux
AlwaysBreakBeforeMultilineStrings: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
IndentCaseLabels: false
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AlignAfterOpenBracket: true
SpaceAfterCStyleCast: false
MaxEmptyLinesToKeep: 2
BreakBeforeBinaryOperators: NonAssignment
BreakStringLiterals: false
SortIncludes: false
IncludeCategories:
- Regex: '^(<|lib)'
Priority: 0
CommentPragmas: '\$(FRR|clippy)'
ContinuationIndentWidth: 8

24
.gitignore vendored
View File

@ -48,18 +48,18 @@ m4/*.m4
debian/autoreconf.after
debian/autoreconf.before
debian/files
debian/quagga-dbg.debhelper.log
debian/quagga-dbg.substvars
debian/quagga-dbg/
debian/quagga-doc.debhelper.log
debian/quagga-doc.substvars
debian/quagga-doc/
debian/quagga.debhelper.log
debian/quagga.postinst.debhelper
debian/quagga.postrm.debhelper
debian/quagga.prerm.debhelper
debian/quagga.substvars
debian/quagga/
debian/frr-dbg.debhelper.log
debian/frr-dbg.substvars
debian/frr-dbg/
debian/frr-doc.debhelper.log
debian/frr-doc.substvars
debian/frr-doc/
debian/frr.debhelper.log
debian/frr.postinst.debhelper
debian/frr.postrm.debhelper
debian/frr.prerm.debhelper
debian/frr.substvars
debian/frr/
debian/tmp/
*.pyc
*.swp

View File

@ -380,3 +380,36 @@ CLI's are a complicated ugly beast. Additions or changes to the CLI
should use a DEFUN to encapsulate one setting as much as is possible.
Additionally as new DEFUN's are added to the system, documentation
should be provided for the new commands.
### Backwards Compatibility
As a general principle, changes to CLI and code in the lib/ directory
should be made in a backwards compatible fashion. This means that
changes that are purely stylistic in nature should be avoided, e.g.,
renaming an existing macro or library function name without any
functional change. When adding new parameters to common functions, it is
also good to consider if this too should be done in a backward
compatible fashion, e.g., by preserving the old form in addition to
adding the new form.
This is not to say that minor or even major functional changes to CLI
and common code should be avoided, but rather that the benefit gained
from a change should be weighed against the added cost/complexity to
existing code. Also, that when making such changes, it is good to
preserve compatibility when possible to do so without introducing
maintenance overhead/cost. It is also important to keep in mind,
existing code includes code that may reside in private repositories (and
is yet to be submitted) or code that has yet to be migrated from Quagga
to FRR.
That said, compatibility measures can (and should) be removed when either:
* they become a significant burden, e.g. when data structures change and
the compatibility measure would need a complex adaptation layer or becomes
flat-out impossible
* some measure of time (dependent on the specific case) has passed, so that
the compatibility grace period is considered expired.
In all cases, compatibility pieces should be marked with compiler/preprocessor
annotations to print warnings at compile time, pointing to the appropriate
update path. A `-Werror` build should fail if compatibility bits are used.

View File

@ -8,9 +8,8 @@ SUBDIRS = lib qpb fpm @ZEBRA@ @LIBRFP@ @RFPTEST@ \
DIST_SUBDIRS = lib qpb fpm zebra bgpd ripd ripngd ospfd ospf6d ldpd \
isisd watchfrr vtysh ospfclient doc m4 pkgsrc redhat tests \
solaris pimd nhrpd eigrpd @LIBRFP@ @RFPTEST@ tools snapcraft \
babeld \
python \
solaris pimd nhrpd eigrpd bgpd/rfp-example/librfp \
bgpd/rfp-example/rfptest tools snapcraft babeld python \
# end
EXTRA_DIST = aclocal.m4 SERVICES REPORTING-BUGS \

View File

@ -1,18 +1,18 @@
#!/bin/sh
# This file is helpful for building quagga from cvs on NetBSD, and
# This file is helpful for building FRR from cvs on NetBSD, and
# probably on any system using pkgsrc.
# One should have readline installed already (pkgsrc/devel/readline).
MAKE=make
# Quagga is currently documented not to require GNU make, but sometimes
# FRR is currently documented not to require GNU make, but sometimes
# BSD make fails. Enable this if statement as a workaround.
if false; then
MAKE=gmake
echo "WARNING: using gmake to work around nonportable makefiles"
fi
# Use /usr/quagga to be independent, and /usr/pkg to overwrite pkgsrc.
# Use /usr/frr to be independent, and /usr/pkg to overwrite pkgsrc.
PREFIX=/usr/pkg
case $1 in

View File

@ -16,7 +16,7 @@ Please supply the following information:
1. Your FRRouting version or if it is from git then the commit reference.
Please try to report bugs against git master or the latest release.
2. FRR daemons you run e.g. bgpd or ripd and full name of your OS. Any
specific options you compiled Quagga with.
specific options you compiled FRR with.
3. Problem description. Copy and paste relative commands and their output to
describe your network setup e.g. "zebra>show ip route".
Please, also give your simple network layout and output of relative OS

View File

@ -290,9 +290,9 @@ DEFUN (babel_network,
ret = babel_enable_if_add (argv[1]->arg);
if (ret < 0) {
vty_outln (vty, "There is same network configuration %s",
vty_out (vty, "There is same network configuration %s\n",
argv[1]->arg);
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
}
return CMD_SUCCESS;
@ -318,8 +318,8 @@ DEFUN (no_babel_network,
ret = babel_enable_if_delete (argv[2]->arg);
if (ret < 0) {
vty_outln (vty, "can't find network %s",argv[2]->arg);
return CMD_WARNING;
vty_out (vty, "can't find network %s\n",argv[2]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
return CMD_SUCCESS;
@ -861,31 +861,31 @@ show_babel_interface_sub (struct vty *vty, struct interface *ifp)
int is_up;
babel_interface_nfo *babel_ifp;
vty_outln (vty, "%s is %s", ifp->name,
vty_out (vty, "%s is %s\n", ifp->name,
((is_up = if_is_operative(ifp)) ? "up" : "down"));
vty_outln (vty, " ifindex %u, MTU %u bytes %s",
vty_out (vty, " ifindex %u, MTU %u bytes %s\n",
ifp->ifindex, MIN(ifp->mtu, ifp->mtu6), if_flag_dump(ifp->flags));
if (!IS_ENABLE(ifp))
{
vty_outln (vty, " Babel protocol is not enabled on this interface");
vty_out (vty, " Babel protocol is not enabled on this interface\n");
return;
}
if (!is_up)
{
vty_outln (vty,
" Babel protocol is enabled, but not running on this interface");
vty_out (vty,
" Babel protocol is enabled, but not running on this interface\n");
return;
}
babel_ifp = babel_get_if_nfo (ifp);
vty_outln (vty, " Babel protocol is running on this interface");
vty_outln (vty, " Operating mode is \"%s\"",
vty_out (vty, " Babel protocol is running on this interface\n");
vty_out (vty, " Operating mode is \"%s\"\n",
CHECK_FLAG(babel_ifp->flags, BABEL_IF_WIRED) ? "wired" : "wireless");
vty_outln (vty, " Split horizon mode is %s",
vty_out (vty, " Split horizon mode is %s\n",
CHECK_FLAG(babel_ifp->flags, BABEL_IF_SPLIT_HORIZON) ? "On" : "Off");
vty_outln (vty, " Hello interval is %u ms", babel_ifp->hello_interval);
vty_outln (vty, " Update interval is %u ms", babel_ifp->update_interval);
vty_outln (vty, " Rxcost multiplier is %u", babel_ifp->cost);
vty_out (vty, " Hello interval is %u ms\n", babel_ifp->hello_interval);
vty_out (vty, " Update interval is %u ms\n", babel_ifp->update_interval);
vty_out (vty, " Rxcost multiplier is %u\n", babel_ifp->cost);
}
DEFUN (show_babel_interface,
@ -907,7 +907,7 @@ DEFUN (show_babel_interface,
}
if ((ifp = if_lookup_by_name (argv[3]->arg, VRF_DEFAULT)) == NULL)
{
vty_outln (vty, "No such interface name");
vty_out (vty, "No such interface name\n");
return CMD_WARNING;
}
show_babel_interface_sub (vty, ifp);
@ -917,9 +917,9 @@ DEFUN (show_babel_interface,
static void
show_babel_neighbour_sub (struct vty *vty, struct neighbour *neigh)
{
vty_outln (vty,
vty_out (vty,
"Neighbour %s dev %s reach %04x rxcost %d txcost %d "
"rtt %s rttcost %d%s.",
"rtt %s rttcost %d%s.\n",
format_address(neigh->address),
neigh->ifp->name,
neigh->reach,
@ -949,7 +949,7 @@ DEFUN (show_babel_neighbour,
}
if ((ifp = if_lookup_by_name (argv[3]->arg, VRF_DEFAULT)) == NULL)
{
vty_outln (vty, "No such interface name");
vty_out (vty, "No such interface name\n");
return CMD_WARNING;
}
FOR_ALL_NEIGHBOURS(neigh) {
@ -1009,9 +1009,9 @@ show_babel_routes_sub(struct babel_route *route, struct vty *vty,
channels[0] = '\0';
}
vty_outln (vty,
vty_out (vty,
"%s metric %d refmetric %d id %s seqno %d%s age %d "
"via %s neigh %s%s%s%s",
"via %s neigh %s%s%s%s\n",
format_prefix(route->src->prefix, route->src->plen),
route_metric(route), route->refmetric,
format_eui64(route->src->id),
@ -1032,7 +1032,7 @@ show_babel_xroutes_sub (struct xroute *xroute, struct vty *vty,
if(prefix && !babel_prefix_eq(prefix, xroute->prefix, xroute->plen))
return;
vty_outln (vty, "%s metric %d (exported)",
vty_out (vty, "%s metric %d (exported)\n",
format_prefix(xroute->prefix, xroute->plen),
xroute->metric);
}
@ -1089,7 +1089,7 @@ DEFUN (show_babel_route_prefix,
ret = str2prefix(argv[3]->arg, &prefix);
if(ret == 0) {
vty_outln (vty, "%% Malformed address");
vty_out (vty, "%% Malformed address\n");
return CMD_WARNING;
}
@ -1138,7 +1138,7 @@ DEFUN (show_babel_route_addr,
ret = inet_aton (argv[3]->arg, &addr);
if (ret <= 0) {
vty_outln (vty, "%% Malformed address");
vty_out (vty, "%% Malformed address\n");
return CMD_WARNING;
}
@ -1147,7 +1147,7 @@ DEFUN (show_babel_route_addr,
ret = str2prefix(buf, &prefix);
if (ret == 0) {
vty_outln (vty, "%% Parse error -- this shouldn't happen");
vty_out (vty, "%% Parse error -- this shouldn't happen\n");
return CMD_WARNING;
}
@ -1196,7 +1196,7 @@ DEFUN (show_babel_route_addr6,
ret = inet_pton (AF_INET6, argv[3]->arg, &addr);
if (ret <= 0) {
vty_outln (vty, "%% Malformed address");
vty_out (vty, "%% Malformed address\n");
return CMD_WARNING;
}
@ -1206,7 +1206,7 @@ DEFUN (show_babel_route_addr6,
ret = str2prefix(buf, &prefix);
if (ret == 0) {
vty_outln (vty, "%% Parse error -- this shouldn't happen");
vty_out (vty, "%% Parse error -- this shouldn't happen\n");
return CMD_WARNING;
}
@ -1244,9 +1244,9 @@ DEFUN (show_babel_parameters,
"Babel information\n"
"Configuration information\n")
{
vty_outln (vty, " -- Babel running configuration --");
vty_out (vty, " -- Babel running configuration --\n");
show_babel_main_configuration(vty);
vty_outln (vty, " -- distribution lists --");
vty_out (vty, " -- distribution lists --\n");
config_show_distribute(vty);
return CMD_SUCCESS;
@ -1321,63 +1321,63 @@ interface_config_write (struct vty *vty)
int write = 0;
for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) {
vty_outln (vty, "interface %s",ifp->name);
vty_out (vty, "interface %s\n",ifp->name);
if (ifp->desc)
vty_outln (vty, " description %s",ifp->desc);
vty_out (vty, " description %s\n",ifp->desc);
babel_interface_nfo *babel_ifp = babel_get_if_nfo (ifp);
/* wireless is the default*/
if (CHECK_FLAG (babel_ifp->flags, BABEL_IF_WIRED))
{
vty_outln (vty, " babel wired");
vty_out (vty, " babel wired\n");
write++;
}
if (babel_ifp->hello_interval != BABEL_DEFAULT_HELLO_INTERVAL)
{
vty_outln (vty, " babel hello-interval %u",
vty_out (vty, " babel hello-interval %u\n",
babel_ifp->hello_interval);
write++;
}
if (babel_ifp->update_interval != BABEL_DEFAULT_UPDATE_INTERVAL)
{
vty_outln (vty, " babel update-interval %u",
vty_out (vty, " babel update-interval %u\n",
babel_ifp->update_interval);
write++;
}
/* Some parameters have different defaults for wired/wireless. */
if (CHECK_FLAG (babel_ifp->flags, BABEL_IF_WIRED)) {
if (!CHECK_FLAG (babel_ifp->flags, BABEL_IF_SPLIT_HORIZON)) {
vty_outln (vty, " no babel split-horizon");
vty_out (vty, " no babel split-horizon\n");
write++;
}
if (babel_ifp->cost != BABEL_DEFAULT_RXCOST_WIRED) {
vty_outln (vty, " babel rxcost %u", babel_ifp->cost);
vty_out (vty, " babel rxcost %u\n", babel_ifp->cost);
write++;
}
if (babel_ifp->channel == BABEL_IF_CHANNEL_INTERFERING) {
vty_outln (vty, " babel channel interfering");
vty_out (vty, " babel channel interfering\n");
write++;
} else if(babel_ifp->channel != BABEL_IF_CHANNEL_NONINTERFERING) {
vty_outln (vty, " babel channel %d",babel_ifp->channel);
vty_out (vty, " babel channel %d\n",babel_ifp->channel);
write++;
}
} else {
if (CHECK_FLAG (babel_ifp->flags, BABEL_IF_SPLIT_HORIZON)) {
vty_outln (vty, " babel split-horizon");
vty_out (vty, " babel split-horizon\n");
write++;
}
if (babel_ifp->cost != BABEL_DEFAULT_RXCOST_WIRELESS) {
vty_outln (vty, " babel rxcost %u", babel_ifp->cost);
vty_out (vty, " babel rxcost %u\n", babel_ifp->cost);
write++;
}
if (babel_ifp->channel == BABEL_IF_CHANNEL_NONINTERFERING) {
vty_outln (vty, " babel channel noninterfering");
vty_out (vty, " babel channel noninterfering\n");
write++;
} else if(babel_ifp->channel != BABEL_IF_CHANNEL_INTERFERING) {
vty_outln (vty, " babel channel %d",babel_ifp->channel);
vty_out (vty, " babel channel %d\n",babel_ifp->channel);
write++;
}
}
vty_outln (vty, "!");
vty_out (vty, "!\n");
write++;
}
return write;
@ -1393,7 +1393,7 @@ babel_enable_if_config_write (struct vty * vty)
for (i = 0; i < vector_active (babel_enable_if); i++)
if ((str = vector_slot (babel_enable_if, i)) != NULL)
{
vty_outln (vty, " network %s", str);
vty_out (vty, " network %s\n", str);
lines++;
}
return lines;

View File

@ -377,25 +377,22 @@ babel_save_state_file(void)
void
show_babel_main_configuration (struct vty *vty)
{
vty_outln (vty,
"state file = %s%s"
"configuration file = %s%s"
"protocol informations:%s"
" multicast address = %s%s"
" port = %d%s"
"vty address = %s%s"
"vty port = %d%s"
"id = %s%s"
"kernel_metric = %d",
state_file, VTYNL,
vty_out (vty,
"state file = %s\n"
"configuration file = %s\n"
"protocol informations:\n"
" multicast address = %s\n"
" port = %d\n"
"vty address = %s\n"
"vty port = %d\n"
"id = %s\n"
"kernel_metric = %d\n",
state_file,
babel_config_file ? babel_config_file : babel_config_default,
VTYNL,
VTYNL,
format_address(protocol_group), VTYNL,
protocol_port, VTYNL,
format_address(protocol_group),
protocol_port,
babel_vty_addr ? babel_vty_addr : "None",
VTYNL,
babel_vty_port, VTYNL,
format_eui64(myid), VTYNL,
babel_vty_port,
format_eui64(myid),
kernel_metric);
}

View File

@ -222,11 +222,12 @@ DEFUN (babel_redistribute_type,
type = babel_proto_redistnum(argv[1]->arg);
if (type < 0) {
vty_outln (vty, "Invalid type %s", argv[1]->arg);
return CMD_WARNING;
vty_out (vty, "Invalid type %s\n", argv[1]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0, VRF_DEFAULT);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
return CMD_SUCCESS;
}
@ -243,11 +244,12 @@ DEFUN (no_babel_redistribute_type,
type = babel_proto_redistnum(argv[2]->arg);
if (type < 0) {
vty_outln (vty, "Invalid type %s", argv[2]->arg);
return CMD_WARNING;
vty_out (vty, "Invalid type %s\n", argv[2]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
/* perhaps should we remove xroutes having the same type... */
return CMD_SUCCESS;
}
@ -277,9 +279,9 @@ DEFUN (debug_babel,
}
}
vty_outln (vty, "Invalid type %s", argv[2]->arg);
vty_out (vty, "Invalid type %s\n", argv[2]->arg);
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
}
/* [Babel Command] */
@ -307,9 +309,9 @@ DEFUN (no_debug_babel,
}
}
vty_outln (vty, "Invalid type %s", argv[3]->arg);
vty_out (vty, "Invalid type %s\n", argv[3]->arg);
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
}
#endif /* NO_DEBUG */
@ -324,7 +326,7 @@ debug_babel_config_write (struct vty * vty)
if (debug == BABEL_DEBUG_ALL)
{
vty_outln (vty, "debug babel all");
vty_out (vty, "debug babel all\n");
lines++;
}
else
@ -335,12 +337,12 @@ debug_babel_config_write (struct vty * vty)
&& CHECK_FLAG (debug, debug_type[i].type)
)
{
vty_outln (vty, "debug babel %s", debug_type[i].str);
vty_out (vty, "debug babel %s\n", debug_type[i].str);
lines++;
}
if (lines)
{
vty_outln (vty, "!");
vty_out (vty, "!\n");
lines++;
}
return lines;
@ -384,13 +386,13 @@ zebra_config_write (struct vty *vty)
{
if (! zclient->enable)
{
vty_outln (vty, "no router zebra");
vty_out (vty, "no router zebra\n");
return 1;
}
else if (! vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BABEL], VRF_DEFAULT))
{
vty_outln (vty, "router zebra");
vty_outln (vty, " no redistribute babel");
vty_out (vty, "router zebra\n");
vty_out (vty, " no redistribute babel\n");
return 1;
}
return 0;

View File

@ -83,25 +83,25 @@ babel_config_write (struct vty *vty)
if (!babel_routing_process)
return lines;
vty_outln (vty, "router babel");
vty_out (vty, "router babel\n");
if (diversity_kind != DIVERSITY_NONE)
{
vty_outln (vty, " babel diversity");
vty_out (vty, " babel diversity\n");
lines++;
}
if (diversity_factor != BABEL_DEFAULT_DIVERSITY_FACTOR)
{
vty_outln (vty, " babel diversity-factor %d",diversity_factor);
vty_out (vty, " babel diversity-factor %d\n",diversity_factor);
lines++;
}
if (resend_delay != BABEL_DEFAULT_RESEND_DELAY)
{
vty_outln (vty, " babel resend-delay %u", resend_delay);
vty_out (vty, " babel resend-delay %u\n", resend_delay);
lines++;
}
if (smoothing_half_life != BABEL_DEFAULT_SMOOTHING_HALF_LIFE)
{
vty_outln (vty, " babel smoothing-half-life %u",
vty_out (vty, " babel smoothing-half-life %u\n",
smoothing_half_life);
lines++;
}
@ -112,7 +112,7 @@ babel_config_write (struct vty *vty)
if (i != zclient->redist_default &&
vrf_bitmap_check (zclient->redist[AFI_IP][i], VRF_DEFAULT))
{
vty_outln (vty, " redistribute %s", zebra_route_string(i));
vty_out (vty, " redistribute %s\n", zebra_route_string(i));
lines++;
}
@ -617,8 +617,7 @@ DEFUN (no_router_babel,
"no router babel",
NO_STR
"Disable a routing process\n"
"Remove Babel instance command\n"
"No attributes\n")
"Remove Babel instance command\n")
{
if(babel_routing_process)
babel_clean_routing_process();

View File

@ -83,7 +83,7 @@ libbgp_a_SOURCES = \
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \
bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \
bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c
bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c bgp_rd.c
noinst_HEADERS = \
bgp_memory.h \
@ -95,7 +95,7 @@ noinst_HEADERS = \
bgp_advertise.h bgp_vty.h bgp_mpath.h bgp_nht.h \
bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h \
$(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \
bgp_vpn.h bgp_label.h
bgp_vpn.h bgp_label.h bgp_rd.h bgp_evpn_private.h
bgpd_SOURCES = bgp_main.c
bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@

View File

@ -43,21 +43,18 @@
/* BGP advertise attribute is used for pack same attribute update into
one packet. To do that we maintain attribute hash in struct
peer. */
struct bgp_advertise_attr *
baa_new (void)
struct bgp_advertise_attr *baa_new(void)
{
return (struct bgp_advertise_attr *)
XCALLOC (MTYPE_BGP_ADVERTISE_ATTR, sizeof (struct bgp_advertise_attr));
return (struct bgp_advertise_attr *)XCALLOC(
MTYPE_BGP_ADVERTISE_ATTR, sizeof(struct bgp_advertise_attr));
}
static void
baa_free (struct bgp_advertise_attr *baa)
static void baa_free(struct bgp_advertise_attr *baa)
{
XFREE(MTYPE_BGP_ADVERTISE_ATTR, baa);
}
static void *
baa_hash_alloc (void *p)
static void *baa_hash_alloc(void *p)
{
struct bgp_advertise_attr *ref = (struct bgp_advertise_attr *)p;
struct bgp_advertise_attr *baa;
@ -67,16 +64,14 @@ baa_hash_alloc (void *p)
return baa;
}
unsigned int
baa_hash_key (void *p)
unsigned int baa_hash_key(void *p)
{
struct bgp_advertise_attr *baa = (struct bgp_advertise_attr *)p;
return attrhash_key_make(baa->attr);
}
int
baa_hash_cmp (const void *p1, const void *p2)
int baa_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_advertise_attr *baa1 = p1;
const struct bgp_advertise_attr *baa2 = p2;
@ -87,23 +82,21 @@ baa_hash_cmp (const void *p1, const void *p2)
/* BGP update and withdraw information is stored in BGP advertise
structure. This structure is referred from BGP adjacency
information. */
struct bgp_advertise *
bgp_advertise_new (void)
struct bgp_advertise *bgp_advertise_new(void)
{
return (struct bgp_advertise *)
XCALLOC (MTYPE_BGP_ADVERTISE, sizeof (struct bgp_advertise));
return (struct bgp_advertise *)XCALLOC(MTYPE_BGP_ADVERTISE,
sizeof(struct bgp_advertise));
}
void
bgp_advertise_free (struct bgp_advertise *adv)
void bgp_advertise_free(struct bgp_advertise *adv)
{
if (adv->binfo)
bgp_info_unlock (adv->binfo); /* bgp_advertise bgp_info reference */
bgp_info_unlock(
adv->binfo); /* bgp_advertise bgp_info reference */
XFREE(MTYPE_BGP_ADVERTISE, adv);
}
void
bgp_advertise_add (struct bgp_advertise_attr *baa,
void bgp_advertise_add(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv)
{
adv->next = baa->adv;
@ -112,8 +105,7 @@ bgp_advertise_add (struct bgp_advertise_attr *baa,
baa->adv = adv;
}
void
bgp_advertise_delete (struct bgp_advertise_attr *baa,
void bgp_advertise_delete(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv)
{
if (adv->next)
@ -124,8 +116,8 @@ bgp_advertise_delete (struct bgp_advertise_attr *baa,
baa->adv = adv->next;
}
struct bgp_advertise_attr *
bgp_advertise_intern (struct hash *hash, struct attr *attr)
struct bgp_advertise_attr *bgp_advertise_intern(struct hash *hash,
struct attr *attr)
{
struct bgp_advertise_attr ref;
struct bgp_advertise_attr *baa;
@ -137,18 +129,15 @@ bgp_advertise_intern (struct hash *hash, struct attr *attr)
return baa;
}
void
bgp_advertise_unintern (struct hash *hash, struct bgp_advertise_attr *baa)
void bgp_advertise_unintern(struct hash *hash, struct bgp_advertise_attr *baa)
{
if (baa->refcnt)
baa->refcnt--;
if (baa->refcnt && baa->attr)
bgp_attr_unintern(&baa->attr);
else
{
if (baa->attr)
{
else {
if (baa->attr) {
hash_release(hash, baa);
bgp_attr_unintern(&baa->attr);
}
@ -156,8 +145,7 @@ bgp_advertise_unintern (struct hash *hash, struct bgp_advertise_attr *baa)
}
}
int
bgp_adj_out_lookup (struct peer *peer, struct bgp_node *rn,
int bgp_adj_out_lookup(struct peer *peer, struct bgp_node *rn,
u_int32_t addpath_tx_id)
{
struct bgp_adj_out *adj;
@ -168,19 +156,19 @@ bgp_adj_out_lookup (struct peer *peer, struct bgp_node *rn,
for (adj = rn->adj_out; adj; adj = adj->next)
SUBGRP_FOREACH_PEER(adj->subgroup, paf)
if (paf->peer == peer)
{
if (paf->peer == peer) {
afi = SUBGRP_AFI(adj->subgroup);
safi = SUBGRP_SAFI(adj->subgroup);
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
/* Match on a specific addpath_tx_id if we are using addpath for this
/* Match on a specific addpath_tx_id if we are using addpath for
* this
* peer and if an addpath_tx_id was specified */
if (addpath_capable && addpath_tx_id && adj->addpath_tx_id != addpath_tx_id)
if (addpath_capable && addpath_tx_id
&& adj->addpath_tx_id != addpath_tx_id)
continue;
return (adj->adv
? (adj->adv->baa ? 1 : 0)
return (adj->adv ? (adj->adv->baa ? 1 : 0)
: (adj->attr ? 1 : 0));
}
@ -188,18 +176,14 @@ bgp_adj_out_lookup (struct peer *peer, struct bgp_node *rn,
}
void
bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr,
void bgp_adj_in_set(struct bgp_node *rn, struct peer *peer, struct attr *attr,
u_int32_t addpath_id)
{
struct bgp_adj_in *adj;
for (adj = rn->adj_in; adj; adj = adj->next)
{
if (adj->peer == peer && adj->addpath_rx_id == addpath_id)
{
if (adj->attr != attr)
{
for (adj = rn->adj_in; adj; adj = adj->next) {
if (adj->peer == peer && adj->addpath_rx_id == addpath_id) {
if (adj->attr != attr) {
bgp_attr_unintern(&adj->attr);
adj->attr = bgp_attr_intern(attr);
}
@ -214,8 +198,7 @@ bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr,
bgp_lock_node(rn);
}
void
bgp_adj_in_remove (struct bgp_node *rn, struct bgp_adj_in *bai)
void bgp_adj_in_remove(struct bgp_node *rn, struct bgp_adj_in *bai)
{
bgp_attr_unintern(&bai->attr);
BGP_ADJ_IN_DEL(rn, bai);
@ -223,8 +206,7 @@ bgp_adj_in_remove (struct bgp_node *rn, struct bgp_adj_in *bai)
XFREE(MTYPE_BGP_ADJ_IN, bai);
}
int
bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer,
int bgp_adj_in_unset(struct bgp_node *rn, struct peer *peer,
u_int32_t addpath_id)
{
struct bgp_adj_in *adj;
@ -235,12 +217,10 @@ bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer,
if (!adj)
return 0;
while (adj)
{
while (adj) {
adj_next = adj->next;
if (adj->peer == peer && adj->addpath_rx_id == addpath_id)
{
if (adj->peer == peer && adj->addpath_rx_id == addpath_id) {
bgp_adj_in_remove(rn, adj);
bgp_unlock_node(rn);
}
@ -251,37 +231,35 @@ bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer,
return 1;
}
void
bgp_sync_init (struct peer *peer)
void bgp_sync_init(struct peer *peer)
{
afi_t afi;
safi_t safi;
struct bgp_synchronize *sync;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
sync = XCALLOC(MTYPE_BGP_SYNCHRONISE,
sizeof(struct bgp_synchronize));
BGP_ADV_FIFO_INIT(&sync->update);
BGP_ADV_FIFO_INIT(&sync->withdraw);
BGP_ADV_FIFO_INIT(&sync->withdraw_low);
peer->sync[afi][safi] = sync;
peer->hash[afi][safi] = hash_create (baa_hash_key, baa_hash_cmp, NULL);
peer->hash[afi][safi] =
hash_create(baa_hash_key, baa_hash_cmp, NULL);
}
}
void
bgp_sync_delete (struct peer *peer)
void bgp_sync_delete(struct peer *peer)
{
afi_t afi;
safi_t safi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
if (peer->sync[afi][safi])
XFREE (MTYPE_BGP_SYNCHRONISE, peer->sync[afi][safi]);
XFREE(MTYPE_BGP_SYNCHRONISE,
peer->sync[afi][safi]);
peer->sync[afi][safi] = NULL;
if (peer->hash[afi][safi])

View File

@ -26,16 +26,14 @@
struct update_subgroup;
/* BGP advertise FIFO. */
struct bgp_advertise_fifo
{
struct bgp_advertise_fifo {
struct bgp_advertise *next;
struct bgp_advertise *prev;
u_int32_t count;
};
/* BGP advertise attribute. */
struct bgp_advertise_attr
{
struct bgp_advertise_attr {
/* Head of advertisement pointer. */
struct bgp_advertise *adv;
@ -46,8 +44,7 @@ struct bgp_advertise_attr
struct attr *attr;
};
struct bgp_advertise
{
struct bgp_advertise {
/* FIFO for advertisement. */
struct bgp_advertise_fifo fifo;
@ -69,8 +66,7 @@ struct bgp_advertise
};
/* BGP adjacency out. */
struct bgp_adj_out
{
struct bgp_adj_out {
/* Lined list pointer. */
struct bgp_adj_out *next;
struct bgp_adj_out *prev;
@ -94,8 +90,7 @@ struct bgp_adj_out
};
/* BGP adjacency in. */
struct bgp_adj_in
{
struct bgp_adj_in {
/* Linked list pointer. */
struct bgp_adj_in *next;
struct bgp_adj_in *prev;
@ -111,8 +106,7 @@ struct bgp_adj_in
};
/* BGP advertisement list. */
struct bgp_synchronize
{
struct bgp_synchronize {
struct bgp_advertise_fifo update;
struct bgp_advertise_fifo withdraw;
struct bgp_advertise_fifo withdraw_low;
@ -161,19 +155,22 @@ struct bgp_synchronize
(F)->count = 0; \
} while (0)
#define BGP_ADV_FIFO_COUNT(F) \
(F)->count
#define BGP_ADV_FIFO_COUNT(F) (F)->count
#define BGP_ADV_FIFO_EMPTY(F) \
(((struct bgp_advertise_fifo *)(F))->next == (struct bgp_advertise *)(F))
(((struct bgp_advertise_fifo *)(F))->next \
== (struct bgp_advertise *)(F))
#define BGP_ADV_FIFO_HEAD(F) \
((((struct bgp_advertise_fifo *)(F))->next == (struct bgp_advertise *)(F)) \
? NULL : (F)->next)
((((struct bgp_advertise_fifo *)(F))->next \
== (struct bgp_advertise *)(F)) \
? NULL \
: (F)->next)
/* Prototypes. */
extern int bgp_adj_out_lookup(struct peer *, struct bgp_node *, u_int32_t);
extern void bgp_adj_in_set (struct bgp_node *, struct peer *, struct attr *, u_int32_t);
extern void bgp_adj_in_set(struct bgp_node *, struct peer *, struct attr *,
u_int32_t);
extern int bgp_adj_in_unset(struct bgp_node *, struct peer *, u_int32_t);
extern void bgp_adj_in_remove(struct bgp_node *, struct bgp_adj_in *);
@ -185,13 +182,12 @@ extern void bgp_advertise_add (struct bgp_advertise_attr *baa,
struct bgp_advertise *adv);
extern struct bgp_advertise *bgp_advertise_new(void);
extern void bgp_advertise_free(struct bgp_advertise *adv);
extern struct bgp_advertise_attr *
bgp_advertise_intern (struct hash *hash, struct attr *attr);
extern struct bgp_advertise_attr *bgp_advertise_intern(struct hash *hash,
struct attr *attr);
extern struct bgp_advertise_attr *baa_new(void);
extern void
bgp_advertise_delete (struct bgp_advertise_attr *baa,
extern void bgp_advertise_delete(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv);
extern void
bgp_advertise_unintern (struct hash *hash, struct bgp_advertise_attr *baa);
extern void bgp_advertise_unintern(struct hash *hash,
struct bgp_advertise_attr *baa);
#endif /* _QUAGGA_BGP_ADVERTISE_H */

File diff suppressed because it is too large Load Diff

View File

@ -44,12 +44,11 @@
#define BGP_AS_TRANS 23456U
#define BGP_AS_IS_PRIVATE(ASN) \
(((ASN) >= BGP_PRIVATE_AS_MIN && (ASN) <= BGP_PRIVATE_AS_MAX) || \
((ASN) >= BGP_PRIVATE_AS4_MIN && (ASN) <= BGP_PRIVATE_AS4_MAX))
(((ASN) >= BGP_PRIVATE_AS_MIN && (ASN) <= BGP_PRIVATE_AS_MAX) \
|| ((ASN) >= BGP_PRIVATE_AS4_MIN && (ASN) <= BGP_PRIVATE_AS4_MAX))
/* AS_PATH segment data in abstracted form, no limit is placed on length */
struct assegment
{
struct assegment {
struct assegment *next;
as_t *as;
u_short length;
@ -57,8 +56,7 @@ struct assegment
};
/* AS path may be include some AsSegments. */
struct aspath
{
struct aspath {
/* Reference count to this aspath. */
unsigned long refcnt;
@ -98,7 +96,8 @@ extern void aspath_free (struct aspath *);
extern struct aspath *aspath_intern(struct aspath *);
extern void aspath_unintern(struct aspath **);
extern const char *aspath_print(struct aspath *);
extern void aspath_print_vty (struct vty *, const char *, struct aspath *, const char *);
extern void aspath_print_vty(struct vty *, const char *, struct aspath *,
const char *);
extern void aspath_print_all_vty(struct vty *);
extern unsigned int aspath_key_make(void *);
extern unsigned int aspath_get_first_as(struct aspath *);
@ -106,8 +105,11 @@ extern unsigned int aspath_get_last_as (struct aspath *);
extern int aspath_loop_check(struct aspath *, as_t);
extern int aspath_private_as_check(struct aspath *);
extern int aspath_single_asn_check(struct aspath *, as_t asn);
extern struct aspath *aspath_replace_specific_asn (struct aspath *aspath, as_t target_asn, as_t our_asn);
extern struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn);
extern struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
as_t target_asn,
as_t our_asn);
extern struct aspath *aspath_replace_private_asns(struct aspath *aspath,
as_t asn);
extern struct aspath *aspath_remove_private_asns(struct aspath *aspath);
extern int aspath_firstas_check(struct aspath *, as_t);
extern int aspath_confed_check(struct aspath *);

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#ifndef _QUAGGA_BGP_ATTR_H
#define _QUAGGA_BGP_ATTR_H
#include "mpls.h"
#include "bgp_attr_evpn.h"
/* Simple bit mapping. */
@ -34,7 +35,6 @@
#define BGP_MED_MAX UINT32_MAX
/* BGP Attribute type range. */
#define BGP_ATTR_TYPE_RANGE 256
#define BGP_ATTR_BITMAP_SIZE (BGP_ATTR_TYPE_RANGE / BITMAP_NBBY)
@ -91,18 +91,38 @@ struct bgp_tea_options {
#endif
/* Overlay Index Info */
struct overlay_index
{
struct overlay_index {
struct eth_segment_id eth_s_id;
union gw_addr gw_ip;
};
/* Additional/uncommon BGP attributes.
* lazily allocated as and when a struct attr
* requires it.
*/
struct attr_extra
{
/* BGP core attribute structure. */
struct attr {
/* AS Path structure */
struct aspath *aspath;
/* Community structure */
struct community *community;
/* Reference count of this attribute. */
unsigned long refcnt;
/* Flag of attribute is set or not. */
uint64_t flag;
/* Apart from in6_addr, the remaining static attributes */
struct in_addr nexthop;
u_int32_t med;
u_int32_t local_pref;
ifindex_t nh_ifindex;
/* Path origin attribute */
u_char origin;
/* has the route-map changed any attribute?
Used on the peer outbound side. */
u_int32_t rmap_change_flags;
/* Multi-Protocol Nexthop, AFI IPv6 */
struct in6_addr mp_nexthop_global;
struct in6_addr mp_nexthop_local;
@ -139,12 +159,18 @@ struct attr_extra
/* MP Nexthop preference */
u_char mp_nexthop_prefer_global;
/* Static MAC for EVPN */
u_char sticky;
/* route tag */
route_tag_t tag;
/* Label index */
u_int32_t label_index;
/* MPLS label */
mpls_label_t label;
uint16_t encap_tunneltype; /* grr */
struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */
@ -153,38 +179,9 @@ struct attr_extra
#endif
/* EVPN */
struct overlay_index evpn_overlay;
};
/* BGP core attribute structure. */
struct attr
{
/* AS Path structure */
struct aspath *aspath;
/* Community structure */
struct community *community;
/* Lazily allocated pointer to extra attributes */
struct attr_extra *extra;
/* Reference count of this attribute. */
unsigned long refcnt;
/* Flag of attribute is set or not. */
uint64_t flag;
/* Apart from in6_addr, the remaining static attributes */
struct in_addr nexthop;
u_int32_t med;
u_int32_t local_pref;
ifindex_t nh_ifindex;
/* Path origin attribute */
u_char origin;
/* has the route-map changed any attribute?
Used on the peer outbound side. */
u_int32_t rmap_change_flags;
/* EVPN MAC Mobility sequence number, if any. */
u_int32_t mm_seqnum;
};
/* rmap_change_flags definition */
@ -197,16 +194,14 @@ struct attr
#define BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED (1 << 6)
/* Router Reflector related structure. */
struct cluster_list
{
struct cluster_list {
unsigned long refcnt;
int length;
struct in_addr *list;
};
/* Unknown transit attribute. */
struct transit
{
struct transit {
unsigned long refcnt;
int length;
u_char *val;
@ -215,15 +210,17 @@ struct transit
#define ATTR_FLAG_BIT(X) (1ULL << ((X) - 1))
#define BGP_CLUSTER_LIST_LENGTH(attr) \
(((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) ? \
(attr)->extra->cluster->length : 0)
(((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) \
? (attr)->cluster->length \
: 0)
typedef enum {
BGP_ATTR_PARSE_PROCEED = 0,
BGP_ATTR_PARSE_ERROR = -1,
BGP_ATTR_PARSE_WITHDRAW = -2,
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR */
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
*/
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
} bgp_attr_parse_ret_t;
@ -235,8 +232,6 @@ extern void bgp_attr_finish (void);
extern bgp_attr_parse_ret_t bgp_attr_parse(struct peer *, struct attr *,
bgp_size_t, struct bgp_nlri *,
struct bgp_nlri *);
extern struct attr_extra *bgp_attr_extra_get (struct attr *);
extern void bgp_attr_extra_free (struct attr *);
extern void bgp_attr_dup(struct attr *, struct attr *);
extern void bgp_attr_deep_dup(struct attr *, struct attr *);
extern void bgp_attr_deep_free(struct attr *);
@ -248,13 +243,14 @@ extern void bgp_attr_flush (struct attr *);
extern struct attr *bgp_attr_default_set(struct attr *attr, u_char);
extern struct attr *bgp_attr_aggregate_intern(struct bgp *, u_char,
struct aspath *,
struct community *, int as_set, u_char);
struct community *, int as_set,
u_char);
extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
struct stream *, struct attr *,
struct bpacket_attr_vec_arr *vecarr,
struct prefix *, afi_t, safi_t,
struct peer *, struct prefix_rd *,
u_char *, int, u_int32_t);
mpls_label_t *, int, u_int32_t);
extern void bgp_dump_routes_attr(struct stream *, struct attr *,
struct prefix *);
extern int attrhash_cmp(const void *, const void *);
@ -288,8 +284,7 @@ extern int bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
extern struct bgp_attr_encap_subtlv *
encap_tlv_dup(struct bgp_attr_encap_subtlv *orig);
extern void
bgp_attr_flush_encap(struct attr *attr);
extern void bgp_attr_flush_encap(struct attr *attr);
/**
* Set of functions to encode MP_REACH_NLRI and MP_UNREACH_NLRI attributes.
@ -303,9 +298,8 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer,
struct attr *attr);
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
struct prefix *p, struct prefix_rd *prd,
u_char *tag, int addpath_encode,
u_int32_t addpath_tx_id,
struct attr *);
mpls_label_t *label, int addpath_encode,
u_int32_t addpath_tx_id, struct attr *);
extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
struct prefix *p);
extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep);
@ -313,20 +307,30 @@ extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep);
extern size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi,
safi_t safi);
extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p,
afi_t afi, safi_t safi, struct prefix_rd *prd,
u_char *tag, int, u_int32_t, struct attr *);
afi_t afi, safi_t safi,
struct prefix_rd *prd, mpls_label_t *,
int, u_int32_t, struct attr *);
extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt);
static inline int
bgp_rmap_nhop_changed(u_int32_t out_rmap_flags, u_int32_t in_rmap_flags)
static inline int bgp_rmap_nhop_changed(u_int32_t out_rmap_flags,
u_int32_t in_rmap_flags)
{
return ((CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_PEER_ADDRESS) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV4_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_LL_NHOP_CHANGED) ||
CHECK_FLAG(in_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED)) ? 1 : 0);
return ((CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_PEER_ADDRESS)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV4_NHOP_CHANGED)
|| CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED)
|| CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_LL_NHOP_CHANGED)
|| CHECK_FLAG(in_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED))
? 1
: 0);
}
static inline u_int32_t mac_mobility_seqnum(struct attr *attr)
{
return (attr) ? attr->mm_seqnum : 0;
}
#endif /* _QUAGGA_BGP_ATTR_H */

View File

@ -33,21 +33,20 @@
#include "bgpd/bgp_attr_evpn.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_evpn.h"
#include "bgpd/bgp_evpn_private.h"
void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac)
{
struct ecommunity_val routermac_ecom;
if (attr->extra) {
memset(&routermac_ecom, 0, sizeof(struct ecommunity_val));
routermac_ecom.val[0] = ECOMMUNITY_ENCODE_EVPN;
routermac_ecom.val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC;
memcpy(&routermac_ecom.val[2], routermac->octet, ETHER_ADDR_LEN);
if (!attr->extra->ecommunity)
attr->extra->ecommunity = ecommunity_new();
ecommunity_add_val(attr->extra->ecommunity, &routermac_ecom);
ecommunity_str (attr->extra->ecommunity);
}
if (!attr->ecommunity)
attr->ecommunity = ecommunity_new();
ecommunity_add_val(attr->ecommunity, &routermac_ecom);
ecommunity_str(attr->ecommunity);
}
/* converts to an esi
@ -62,10 +61,9 @@ int str2esi(const char *str, struct eth_segment_id *id)
if (!str)
return 0;
if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x",
a + 0, a + 1, a + 2, a + 3, a + 4, a + 5,
a + 6, a + 7, a + 8, a + 9) != ESI_LEN)
{
if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1,
a + 2, a + 3, a + 4, a + 5, a + 6, a + 7, a + 8, a + 9)
!= ESI_LEN) {
/* error in incoming str length */
return 0;
}
@ -86,12 +84,13 @@ char *esi2str(struct eth_segment_id *id)
return NULL;
val = id->val;
ptr = (char *)XMALLOC(MTYPE_TMP, (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
ptr = (char *)XMALLOC(MTYPE_TMP,
(ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
snprintf(ptr, (ESI_LEN * 2 + ESI_LEN - 1 + 1),
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
val[0], val[1], val[2], val[3], val[4],
val[5], val[6], val[7], val[8], val[9]);
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", val[0],
val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8],
val[9]);
return ptr;
}
@ -102,12 +101,63 @@ char *ecom_mac2str(char *ecom_mac)
en = ecom_mac;
en += 2;
return prefix_mac2str((struct ethaddr *)en, NULL, 0);
}
/*
* Fetch and return the sequence number from MAC Mobility extended
* community, if present, else 0.
*/
u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, u_char *sticky)
{
struct ecommunity *ecom;
int i;
u_char flags = 0;
ecom = attr->ecommunity;
if (!ecom || !ecom->size)
return 0;
/* If there is a MAC Mobility extended community, return its
* sequence number.
* TODO: RFC is silent on handling of multiple MAC mobility extended
* communities for the same route. We will bail out upon the first
* one.
*/
for (i = 0; i < ecom->size; i++) {
u_char *pnt;
u_char type, sub_type;
u_int32_t seq_num;
pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
type = *pnt++;
sub_type = *pnt++;
if (!(type == ECOMMUNITY_ENCODE_EVPN
&& sub_type == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY))
continue;
flags = *pnt++;
if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY)
*sticky = 1;
else
*sticky = 0;
pnt++;
seq_num = (*pnt++ << 24);
seq_num |= (*pnt++ << 16);
seq_num |= (*pnt++ << 8);
seq_num |= (*pnt++);
return seq_num;
}
return 0;
}
/* dst prefix must be AF_INET or AF_INET6 prefix, to forge EVPN prefix */
extern int
bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
extern int bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag,
struct prefix *dst)
{
struct evpn_addr *p_evpn_p;
struct prefix p2;
@ -121,17 +171,17 @@ bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
p_evpn_p = &(dst->u.prefix_evpn);
dst->family = AF_ETHERNET;
p_evpn_p->route_type = evpn_type;
if (evpn_type == EVPN_IP_PREFIX) {
if (evpn_type == BGP_EVPN_IP_PREFIX_ROUTE) {
p_evpn_p->eth_tag = eth_tag;
p_evpn_p->ip_prefix_length = p2.prefixlen;
if (src->family == AF_INET) {
p_evpn_p->flags = IP_PREFIX_V4;
memcpy(&p_evpn_p->ip.v4_addr, &src->u.prefix4,
SET_IPADDR_V4(&p_evpn_p->ip);
memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4,
sizeof(struct in_addr));
dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV4;
} else {
p_evpn_p->flags = IP_PREFIX_V6;
memcpy(&p_evpn_p->ip.v6_addr, &src->u.prefix6,
SET_IPADDR_V6(&p_evpn_p->ip);
memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6,
sizeof(struct in6_addr));
dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV6;
}

View File

@ -28,10 +28,12 @@
#define ESI_TYPE_MAC 3 /* <Syst Mac Add-6B>:<Local Discriminator Value-3B> */
#define ESI_TYPE_ROUTER 4 /* <RouterId-4B>:<Local Discriminator Value-4B> */
#define ESI_TYPE_AS 5 /* <AS-4B>:<Local Discriminator Value-4B> */
#define MAX_ESI {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}
#define ESI_LEN 10
#define MAX_ET 0xffffffff
u_long eth_tag_id;
struct attr;
@ -53,7 +55,12 @@ extern int str2esi(const char *str, struct eth_segment_id *id);
extern char *esi2str(struct eth_segment_id *id);
extern char *ecom_mac2str(char *ecom_mac);
extern void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac);
extern void bgp_add_routermac_ecom(struct attr *attr,
struct ethaddr *routermac);
extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag,
struct prefix *dst);
extern u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr,
u_char *sticky);
#endif /* _QUAGGA_BGP_ATTR_EVPN_H */

View File

@ -43,11 +43,11 @@
extern struct zclient *zclient;
/*
* bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group template
* bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group
* template
* to peer.
*/
void
bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
{
struct bfd_info *bfd_info;
struct bfd_info *conf_bfd_info;
@ -69,10 +69,10 @@ bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
}
/*
* bgp_bfd_is_peer_multihop - returns whether BFD peer is multi-hop or single hop.
* bgp_bfd_is_peer_multihop - returns whether BFD peer is multi-hop or single
* hop.
*/
int
bgp_bfd_is_peer_multihop(struct peer *peer)
int bgp_bfd_is_peer_multihop(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -81,9 +81,9 @@ bgp_bfd_is_peer_multihop(struct peer *peer)
if (!bfd_info)
return 0;
if((bfd_info->type == BFD_TYPE_MULTIHOP) ||
((peer->sort == BGP_PEER_IBGP) && !peer->shared_network) ||
is_ebgp_multihop_configured(peer))
if ((bfd_info->type == BFD_TYPE_MULTIHOP)
|| ((peer->sort == BGP_PEER_IBGP) && !peer->shared_network)
|| is_ebgp_multihop_configured(peer))
return 1;
else
return 0;
@ -93,8 +93,7 @@ bgp_bfd_is_peer_multihop(struct peer *peer)
* bgp_bfd_peer_sendmsg - Format and send a Peer register/Unregister
* command to Zebra to be forwarded to BFD
*/
static void
bgp_bfd_peer_sendmsg (struct peer *peer, int command)
static void bgp_bfd_peer_sendmsg(struct peer *peer, int command)
{
struct bfd_info *bfd_info;
vrf_id_t vrf_id = VRF_DEFAULT;
@ -105,28 +104,27 @@ bgp_bfd_peer_sendmsg (struct peer *peer, int command)
if (peer->bgp && (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VRF))
vrf_id = peer->bgp->vrf_id;
if (command == ZEBRA_BFD_DEST_DEREGISTER)
{
multihop = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
if (command == ZEBRA_BFD_DEST_DEREGISTER) {
multihop =
CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
}
else
{
} else {
multihop = bgp_bfd_is_peer_multihop(peer);
if ((command == ZEBRA_BFD_DEST_REGISTER) && multihop)
SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
}
if (peer->su.sa.sa_family == AF_INET)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
&peer->su.sin.sin_addr,
bfd_peer_sendmsg(
zclient, bfd_info, AF_INET, &peer->su.sin.sin_addr,
(peer->su_local) ? &peer->su_local->sin.sin_addr : NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, multihop, command, 1, vrf_id);
else if (peer->su.sa.sa_family == AF_INET6)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET6,
&peer->su.sin6.sin6_addr,
(peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL,
bfd_peer_sendmsg(
zclient, bfd_info, AF_INET6, &peer->su.sin6.sin6_addr,
(peer->su_local) ? &peer->su_local->sin6.sin6_addr
: NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, multihop, command, 1, vrf_id);
}
@ -135,8 +133,7 @@ bgp_bfd_peer_sendmsg (struct peer *peer, int command)
* bgp_bfd_register_peer - register a peer with BFD through zebra
* for monitoring the peer rechahability.
*/
void
bgp_bfd_register_peer (struct peer *peer)
void bgp_bfd_register_peer(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -144,7 +141,8 @@ bgp_bfd_register_peer (struct peer *peer)
return;
bfd_info = (struct bfd_info *)peer->bfd_info;
/* Check if BFD is enabled and peer has already been registered with BFD */
/* Check if BFD is enabled and peer has already been registered with BFD
*/
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
return;
@ -156,8 +154,7 @@ bgp_bfd_register_peer (struct peer *peer)
* for stopping the monitoring of the peer
* rechahability.
*/
void
bgp_bfd_deregister_peer (struct peer *peer)
void bgp_bfd_deregister_peer(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -179,8 +176,7 @@ bgp_bfd_deregister_peer (struct peer *peer)
* bgp_bfd_update_peer - update peer with BFD with new BFD paramters
* through zebra.
*/
static void
bgp_bfd_update_peer (struct peer *peer)
static void bgp_bfd_update_peer(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -198,8 +194,7 @@ bgp_bfd_update_peer (struct peer *peer)
/*
* bgp_bfd_update_type - update session type with BFD through zebra.
*/
static void
bgp_bfd_update_type (struct peer *peer)
static void bgp_bfd_update_type(struct peer *peer)
{
struct bfd_info *bfd_info;
int multihop;
@ -212,23 +207,23 @@ bgp_bfd_update_type (struct peer *peer)
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
return;
if (bfd_info->type == BFD_TYPE_NOT_CONFIGURED)
{
if (bfd_info->type == BFD_TYPE_NOT_CONFIGURED) {
multihop = bgp_bfd_is_peer_multihop(peer);
if ((multihop && !CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
(!multihop && CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
{
if ((multihop
&& !CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))
|| (!multihop && CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))) {
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
}
}
else
{
if ((bfd_info->type == BFD_TYPE_MULTIHOP &&
!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
(bfd_info->type == BFD_TYPE_SINGLEHOP &&
CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
{
} else {
if ((bfd_info->type == BFD_TYPE_MULTIHOP
&& !CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))
|| (bfd_info->type == BFD_TYPE_SINGLEHOP
&& CHECK_FLAG(bfd_info->flags,
BFD_FLAG_BFD_TYPE_MULTIHOP))) {
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
}
@ -239,9 +234,8 @@ bgp_bfd_update_type (struct peer *peer)
* bgp_bfd_dest_replay - Replay all the peers that have BFD enabled
* to zebra
*/
static int
bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length,
vrf_id_t vrf_id)
static int bgp_bfd_dest_replay(int command, struct zclient *client,
zebra_size_t length, vrf_id_t vrf_id)
{
struct listnode *mnode, *node, *nnode;
struct bgp *bgp;
@ -256,8 +250,7 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length,
/* Replay the peer, if BFD is enabled in BGP */
for (ALL_LIST_ELEMENTS_RO(bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
bgp_bfd_update_peer(peer);
}
@ -266,10 +259,10 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length,
/*
* bgp_bfd_peer_status_update - Update the BFD status if it has changed. Bring
* down the peer if the BFD session went down from * up.
* down the peer if the BFD session went down from
* * up.
*/
static void
bgp_bfd_peer_status_update (struct peer *peer, int status)
static void bgp_bfd_peer_status_update(struct peer *peer, int status)
{
struct bfd_info *bfd_info;
int old_status;
@ -283,8 +276,7 @@ bgp_bfd_peer_status_update (struct peer *peer, int status)
bfd_info->status = status;
bfd_info->last_update = bgp_clock();
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
{
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) {
peer->last_reset = PEER_DOWN_BFD_DOWN;
BGP_EVENT_ADD(peer, BGP_Stop);
}
@ -295,8 +287,7 @@ bgp_bfd_peer_status_update (struct peer *peer, int status)
* has changed and bring down the peer
* connectivity if the BFD session went down.
*/
static int
bgp_bfd_dest_update (int command, struct zclient *zclient,
static int bgp_bfd_dest_update(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp;
@ -306,20 +297,20 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status, vrf_id);
if (BGP_DEBUG (zebra, ZEBRA))
{
if (BGP_DEBUG(zebra, ZEBRA)) {
char buf[2][PREFIX2STR_BUFFER];
prefix2str(&dp, buf[0], sizeof(buf[0]));
if (ifp)
{
zlog_debug("Zebra: vrf %d interface %s bfd destination %s %s",
vrf_id, ifp->name, buf[0], bfd_get_status_str(status));
}
else
{
if (ifp) {
zlog_debug(
"Zebra: vrf %d interface %s bfd destination %s %s",
vrf_id, ifp->name, buf[0],
bfd_get_status_str(status));
} else {
prefix2str(&sp, buf[1], sizeof(buf[1]));
zlog_debug("Zebra: vrf %d source %s bfd destination %s %s",
vrf_id, buf[1], buf[0], bfd_get_status_str(status));
zlog_debug(
"Zebra: vrf %d source %s bfd destination %s %s",
vrf_id, buf[1], buf[0],
bfd_get_status_str(status));
}
}
@ -330,55 +321,58 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
struct peer *peer;
for (ALL_LIST_ELEMENTS_RO(bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (!peer->bfd_info)
continue;
if ((dp.family == AF_INET) && (peer->su.sa.sa_family == AF_INET))
{
if (dp.u.prefix4.s_addr != peer->su.sin.sin_addr.s_addr)
if ((dp.family == AF_INET)
&& (peer->su.sa.sa_family == AF_INET)) {
if (dp.u.prefix4.s_addr
!= peer->su.sin.sin_addr.s_addr)
continue;
}
else if ((dp.family == AF_INET6) &&
(peer->su.sa.sa_family == AF_INET6))
{
if (memcmp(&dp.u.prefix6, &peer->su.sin6.sin6_addr,
} else if ((dp.family == AF_INET6)
&& (peer->su.sa.sa_family
== AF_INET6)) {
if (memcmp(&dp.u.prefix6,
&peer->su.sin6.sin6_addr,
sizeof(struct in6_addr)))
continue;
}
else
} else
continue;
if (ifp && (ifp == peer->nexthop.ifp))
{
bgp_bfd_peer_status_update(peer, status);
}
else
{
if (ifp && (ifp == peer->nexthop.ifp)) {
bgp_bfd_peer_status_update(peer,
status);
} else {
if (!peer->su_local)
continue;
if ((sp.family == AF_INET) &&
(peer->su_local->sa.sa_family == AF_INET))
{
if (sp.u.prefix4.s_addr != peer->su_local->sin.sin_addr.s_addr)
if ((sp.family == AF_INET)
&& (peer->su_local->sa.sa_family
== AF_INET)) {
if (sp.u.prefix4.s_addr
!= peer->su_local->sin
.sin_addr.s_addr)
continue;
}
else if ((sp.family == AF_INET6) &&
(peer->su_local->sa.sa_family == AF_INET6))
{
if (memcmp(&sp.u.prefix6, &peer->su_local->sin6.sin6_addr,
sizeof (struct in6_addr)))
} else if ((sp.family == AF_INET6)
&& (peer->su_local->sa
.sa_family
== AF_INET6)) {
if (memcmp(&sp.u.prefix6,
&peer->su_local->sin6
.sin6_addr,
sizeof(struct
in6_addr)))
continue;
}
else
} else
continue;
if ((vrf_id != VRF_DEFAULT) && (peer->bgp->vrf_id != vrf_id))
if ((vrf_id != VRF_DEFAULT)
&& (peer->bgp->vrf_id != vrf_id))
continue;
bgp_bfd_peer_status_update(peer, status);
bgp_bfd_peer_status_update(peer,
status);
}
}
}
@ -389,9 +383,9 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
/*
* bgp_bfd_peer_param_set - Set the configured BFD paramter values for peer.
*/
static int
bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
u_int8_t detect_mult, int defaults)
static int bgp_bfd_peer_param_set(struct peer *peer, u_int32_t min_rx,
u_int32_t min_tx, u_int8_t detect_mult,
int defaults)
{
struct peer_group *group;
struct listnode *node, *nnode;
@ -400,26 +394,23 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
detect_mult, defaults, &command);
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
command = 0;
bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
detect_mult, defaults, &command);
bfd_set_param((struct bfd_info **)&(peer->bfd_info),
min_rx, min_tx, detect_mult, defaults,
&command);
if ((peer->status == Established) &&
(command == ZEBRA_BFD_DEST_REGISTER))
if ((peer->status == Established)
&& (command == ZEBRA_BFD_DEST_REGISTER))
bgp_bfd_register_peer(peer);
else if (command == ZEBRA_BFD_DEST_UPDATE)
bgp_bfd_update_peer(peer);
}
}
else
{
if ((peer->status == Established) &&
(command == ZEBRA_BFD_DEST_REGISTER))
} else {
if ((peer->status == Established)
&& (command == ZEBRA_BFD_DEST_REGISTER))
bgp_bfd_register_peer(peer);
else if (command == ZEBRA_BFD_DEST_UPDATE)
bgp_bfd_update_peer(peer);
@ -428,10 +419,10 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
}
/*
* bgp_bfd_peer_param_unset - Delete the configured BFD paramter values for peer.
* bgp_bfd_peer_param_unset - Delete the configured BFD paramter values for
* peer.
*/
static int
bgp_bfd_peer_param_unset (struct peer *peer)
static int bgp_bfd_peer_param_unset(struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
@ -439,18 +430,14 @@ bgp_bfd_peer_param_unset (struct peer *peer)
if (!peer->bfd_info)
return 0;
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
bfd_info_free(&(peer->bfd_info));
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
bgp_bfd_deregister_peer(peer);
bfd_info_free(&(peer->bfd_info));
}
}
else
{
} else {
bgp_bfd_deregister_peer(peer);
bfd_info_free(&(peer->bfd_info));
}
@ -458,29 +445,17 @@ bgp_bfd_peer_param_unset (struct peer *peer)
}
/*
* bgp_bfd_peer_param_type_set - set the BFD session type (multihop or singlehop)
* bgp_bfd_peer_param_type_set - set the BFD session type (multihop or
* singlehop)
*/
static int
bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
static int bgp_bfd_peer_param_type_set(struct peer *peer,
enum bfd_sess_type type)
{
struct peer_group *group;
struct listnode *node, *nnode;
int command = 0;
struct bfd_info *bfd_info;
if (!peer->bfd_info)
bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX,
BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, 1, &command);
bfd_info = (struct bfd_info *)peer->bfd_info;
bfd_info->type = type;
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
command = 0;
if (!peer->bfd_info)
bfd_set_param((struct bfd_info **)&(peer->bfd_info),
BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
@ -489,19 +464,28 @@ bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
bfd_info = (struct bfd_info *)peer->bfd_info;
bfd_info->type = type;
if (peer->status == Established)
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
group = peer->group;
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
command = 0;
if (!peer->bfd_info)
bfd_set_param(
(struct bfd_info **)&(peer->bfd_info),
BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1, &command);
bfd_info = (struct bfd_info *)peer->bfd_info;
bfd_info->type = type;
if (peer->status == Established) {
if (command == ZEBRA_BFD_DEST_REGISTER)
bgp_bfd_register_peer(peer);
else
bgp_bfd_update_type(peer);
}
}
}
else
{
if (peer->status == Established)
{
} else {
if (peer->status == Established) {
if (command == ZEBRA_BFD_DEST_REGISTER)
bgp_bfd_register_peer(peer);
else
@ -515,8 +499,7 @@ bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
/*
* bgp_bfd_peer_config_write - Write the peer BFD configuration.
*/
void
bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
{
struct bfd_info *bfd_info;
@ -526,24 +509,25 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
bfd_info = (struct bfd_info *)peer->bfd_info;
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_outln (vty, " neighbor %s bfd %d %d %d", addr,
vty_out(vty, " neighbor %s bfd %d %d %d\n", addr,
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx);
if (bfd_info->type != BFD_TYPE_NOT_CONFIGURED)
vty_outln (vty, " neighbor %s bfd %s", addr,
(bfd_info->type == BFD_TYPE_MULTIHOP) ? "multihop" : "singlehop");
vty_out(vty, " neighbor %s bfd %s\n", addr,
(bfd_info->type == BFD_TYPE_MULTIHOP) ? "multihop"
: "singlehop");
if (!CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG) &&
(bfd_info->type == BFD_TYPE_NOT_CONFIGURED))
vty_outln (vty, " neighbor %s bfd", addr);
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)
&& (bfd_info->type == BFD_TYPE_NOT_CONFIGURED))
vty_out(vty, " neighbor %s bfd\n", addr);
}
/*
* bgp_bfd_show_info - Show the peer BFD information.
*/
void
bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh)
void bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json,
json_object *json_neigh)
{
bfd_show_info(vty, (struct bfd_info *)peer->bfd_info,
bgp_bfd_is_peer_multihop(peer), 0, use_json, json_neigh);
@ -562,7 +546,7 @@ DEFUN (neighbor_bfd,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
ret = bgp_bfd_peer_param_set(peer, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1);
@ -570,7 +554,6 @@ DEFUN (neighbor_bfd,
return bgp_vty_return(vty, ret);
return CMD_SUCCESS;
}
DEFUN (neighbor_bfd_param,
@ -595,10 +578,12 @@ DEFUN (neighbor_bfd_param,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
if ((ret = bfd_validate_param (vty, argv[idx_number_1]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg, &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
if ((ret = bfd_validate_param(
vty, argv[idx_number_1]->arg, argv[idx_number_2]->arg,
argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
!= CMD_SUCCESS)
return ret;
ret = bgp_bfd_peer_param_set(peer, rx_val, tx_val, dm_val, 0);
@ -606,7 +591,6 @@ DEFUN (neighbor_bfd_param,
return bgp_vty_return(vty, ret);
return CMD_SUCCESS;
}
DEFUN_HIDDEN (neighbor_bfd_type,
@ -626,14 +610,14 @@ DEFUN_HIDDEN (neighbor_bfd_type,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
if (strmatch(argv[idx_hop]->text, "singlehop"))
type = BFD_TYPE_SINGLEHOP;
else if (strmatch(argv[idx_hop]->text, "multihop"))
type = BFD_TYPE_MULTIHOP;
else
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
ret = bgp_bfd_peer_param_type_set(peer, type);
if (ret != 0)
@ -659,7 +643,7 @@ DEFUN (no_neighbor_bfd,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
ret = bgp_bfd_peer_param_unset(peer);
if (ret != 0)
@ -685,7 +669,7 @@ DEFUN_HIDDEN (no_neighbor_bfd_type,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
if (!peer->bfd_info)
return 0;
@ -697,8 +681,7 @@ DEFUN_HIDDEN (no_neighbor_bfd_type,
return CMD_SUCCESS;
}
void
bgp_bfd_init(void)
void bgp_bfd_init(void)
{
bfd_gbl_init();

View File

@ -23,25 +23,20 @@
#ifndef _QUAGGA_BGP_BFD_H
#define _QUAGGA_BGP_BFD_H
extern void
bgp_bfd_init(void);
extern void bgp_bfd_init(void);
extern void
bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer);
extern void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer);
extern void
bgp_bfd_register_peer (struct peer *peer);
extern void bgp_bfd_register_peer(struct peer *peer);
extern void
bgp_bfd_deregister_peer (struct peer *peer);
extern void bgp_bfd_deregister_peer(struct peer *peer);
extern void
bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr);
extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer,
char *addr);
extern void
bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh);
extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer,
u_char use_json, json_object *json_neigh);
extern int
bgp_bfd_is_peer_multihop(struct peer *peer);
extern int bgp_bfd_is_peer_multihop(struct peer *peer);
#endif /* _QUAGGA_BGP_BFD_H */

View File

@ -35,15 +35,11 @@
#include "bgpd/bgp_aspath.h"
/* privileges */
static zebra_capabilities_t _caps_p [] =
{
ZCAP_BIND,
ZCAP_NET_RAW,
ZCAP_NET_ADMIN,
static zebra_capabilities_t _caps_p[] = {
ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN,
};
struct zebra_privs_t bgpd_privs =
{
struct zebra_privs_t bgpd_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP)
.user = FRR_USER,
.group = FRR_GROUP,
@ -72,8 +68,7 @@ enum MRT_MSG_TYPES {
MSG_TABLE_DUMP /* routing table dump */
};
static int
attr_parse (struct stream *s, u_int16_t len)
static int attr_parse(struct stream *s, u_int16_t len)
{
u_int flag;
u_int type;
@ -84,8 +79,7 @@ attr_parse (struct stream *s, u_int16_t len)
printf("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);
while (s->getp < lim)
{
while (s->getp < lim) {
flag = stream_getc(s);
type = stream_getc(s);
@ -98,31 +92,24 @@ attr_parse (struct stream *s, u_int16_t len)
printf("TYPE: %d\n", type);
printf("Len: %d\n", length);
switch (type)
{
case BGP_ATTR_ORIGIN:
{
switch (type) {
case BGP_ATTR_ORIGIN: {
u_char origin;
origin = stream_getc(s);
printf("ORIGIN: %d\n", origin);
}
break;
case BGP_ATTR_AS_PATH:
{
} break;
case BGP_ATTR_AS_PATH: {
struct aspath *aspath;
aspath = aspath_parse(s, length, 1);
printf("ASPATH: %s\n", aspath->str);
aspath_free(aspath);
}
break;
case BGP_ATTR_NEXT_HOP:
{
} break;
case BGP_ATTR_NEXT_HOP: {
struct in_addr nexthop;
nexthop.s_addr = stream_get_ipv4(s);
printf("NEXTHOP: %s\n", inet_ntoa(nexthop));
}
break;
} break;
default:
stream_getw_from(s, length);
break;
@ -132,8 +119,7 @@ attr_parse (struct stream *s, u_int16_t len)
return 0;
}
int
main (int argc, char **argv)
int main(int argc, char **argv)
{
int ret;
FILE *fp;
@ -153,31 +139,27 @@ main (int argc, char **argv)
s = stream_new(10000);
if (argc != 2)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
exit(1);
}
fp = fopen(argv[1], "r");
if (!fp)
{
fprintf (stdout,"%% Can't open configuration file %s due to '%s'.\n",
if (!fp) {
fprintf(stdout,
"%% Can't open configuration file %s due to '%s'.\n",
argv[1], safe_strerror(errno));
exit(1);
}
while (1)
{
while (1) {
stream_reset(s);
ret = fread(s->data, 12, 1, fp);
if (!ret || feof (fp))
{
if (!ret || feof(fp)) {
printf("END OF FILE\n");
break;
}
if (ferror (fp))
{
if (ferror(fp)) {
printf("ERROR OF FREAD\n");
break;
}
@ -202,8 +184,7 @@ main (int argc, char **argv)
printf("TYPE: Unknown %d", type);
if (type == MSG_TABLE_DUMP)
switch (subtype)
{
switch (subtype) {
case AFI_IP:
printf("/AFI_IP\n");
break;
@ -214,10 +195,8 @@ main (int argc, char **argv)
printf("/UNKNOWN %d", subtype);
break;
}
else
{
switch (subtype)
{
else {
switch (subtype) {
case BGP4MP_STATE_CHANGE:
printf("/CHANGE\n");
break;
@ -239,21 +218,18 @@ main (int argc, char **argv)
printf("len: %zd\n", len);
fread(s->data + 12, len, 1, fp);
if (feof (fp))
{
if (feof(fp)) {
printf("ENDOF FILE 2\n");
break;
}
if (ferror (fp))
{
if (ferror(fp)) {
printf("ERROR OF FREAD 2\n");
break;
}
/* printf ("now read %d\n", len); */
if (type == MSG_TABLE_DUMP)
{
if (type == MSG_TABLE_DUMP) {
u_char status;
time_t originated;
struct in_addr peer;
@ -265,18 +241,19 @@ main (int argc, char **argv)
printf("SEQUENCE: %d\n", seq_num);
/* start */
while (s->getp < len - 16)
{
while (s->getp < len - 16) {
p.prefix.s_addr = stream_get_ipv4(s);
p.prefixlen = stream_getc(s);
printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen);
printf("PREFIX: %s/%d\n", inet_ntoa(p.prefix),
p.prefixlen);
status = stream_getc(s);
originated = stream_getl(s);
peer.s_addr = stream_get_ipv4(s);
source_as = stream_getw(s);
printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as);
printf("FROM: %s AS%d\n", inet_ntoa(peer),
source_as);
printf("ORIGINATED: %s", ctime(&originated));
attrlen = stream_getw(s);
@ -286,9 +263,7 @@ main (int argc, char **argv)
printf("STATUS: 0x%x\n", status);
}
}
else
{
} else {
source_as = stream_getw(s);
dest_as = stream_getw(s);
printf("source_as: %d\n", source_as);

View File

@ -40,8 +40,7 @@ struct community_list_master *
community_list_master_lookup(struct community_list_handler *ch, int master)
{
if (ch)
switch (master)
{
switch (master) {
case COMMUNITY_LIST_MASTER:
return &ch->community_list;
case EXTCOMMUNITY_LIST_MASTER:
@ -53,18 +52,16 @@ community_list_master_lookup (struct community_list_handler *ch, int master)
}
/* Allocate a new community list entry. */
static struct community_entry *
community_entry_new (void)
static struct community_entry *community_entry_new(void)
{
return XCALLOC (MTYPE_COMMUNITY_LIST_ENTRY, sizeof (struct community_entry));
return XCALLOC(MTYPE_COMMUNITY_LIST_ENTRY,
sizeof(struct community_entry));
}
/* Free community list entry. */
static void
community_entry_free (struct community_entry *entry)
{
switch (entry->style)
static void community_entry_free(struct community_entry *entry)
{
switch (entry->style) {
case COMMUNITY_LIST_STANDARD:
if (entry->u.com)
community_free(entry->u.com);
@ -95,15 +92,13 @@ community_entry_free (struct community_entry *entry)
}
/* Allocate a new community-list. */
static struct community_list *
community_list_new (void)
static struct community_list *community_list_new(void)
{
return XCALLOC(MTYPE_COMMUNITY_LIST, sizeof(struct community_list));
}
/* Free community-list. */
static void
community_list_free (struct community_list *list)
static void community_list_free(struct community_list *list)
{
if (list->name)
XFREE(MTYPE_COMMUNITY_LIST_NAME, list->name);
@ -111,8 +106,8 @@ community_list_free (struct community_list *list)
}
static struct community_list *
community_list_insert (struct community_list_handler *ch,
const char *name, int master)
community_list_insert(struct community_list_handler *ch, const char *name,
int master)
{
size_t i;
long number;
@ -132,8 +127,7 @@ community_list_insert (struct community_list_handler *ch,
/* If name is made by all digit character. We treat it as
number. */
for (number = 0, i = 0; i < strlen (name); i++)
{
for (number = 0, i = 0; i < strlen(name); i++) {
if (isdigit((int)name[i]))
number = (number * 10) + (name[i] - '0');
else
@ -141,8 +135,7 @@ community_list_insert (struct community_list_handler *ch,
}
/* In case of name is all digit character */
if (i == strlen (name))
{
if (i == strlen(name)) {
new->sort = COMMUNITY_LIST_NUMBER;
/* Set access_list to number list. */
@ -151,9 +144,7 @@ community_list_insert (struct community_list_handler *ch,
for (point = list->head; point; point = point->next)
if (atol(point->name) >= number)
break;
}
else
{
} else {
new->sort = COMMUNITY_LIST_STRING;
/* Set access_list to string list. */
@ -169,15 +160,13 @@ community_list_insert (struct community_list_handler *ch,
new->parent = list;
/* In case of this is the first element of master. */
if (list->head == NULL)
{
if (list->head == NULL) {
list->head = list->tail = new;
return new;
}
/* In case of insertion is made at the tail of access_list. */
if (point == NULL)
{
if (point == NULL) {
new->prev = list->tail;
list->tail->next = new;
list->tail = new;
@ -185,8 +174,7 @@ community_list_insert (struct community_list_handler *ch,
}
/* In case of insertion is made at the head of access_list. */
if (point == list->head)
{
if (point == list->head) {
new->next = list->head;
list->head->prev = new;
list->head = new;
@ -204,8 +192,7 @@ community_list_insert (struct community_list_handler *ch,
return new;
}
struct community_list *
community_list_lookup (struct community_list_handler *ch,
struct community_list *community_list_lookup(struct community_list_handler *ch,
const char *name, int master)
{
struct community_list *list;
@ -229,8 +216,8 @@ community_list_lookup (struct community_list_handler *ch,
}
static struct community_list *
community_list_get (struct community_list_handler *ch,
const char *name, int master)
community_list_get(struct community_list_handler *ch, const char *name,
int master)
{
struct community_list *list;
@ -240,14 +227,12 @@ community_list_get (struct community_list_handler *ch,
return list;
}
static void
community_list_delete (struct community_list *list)
static void community_list_delete(struct community_list *list)
{
struct community_list_list *clist;
struct community_entry *entry, *next;
for (entry = list->head; entry; entry = next)
{
for (entry = list->head; entry; entry = next) {
next = entry->next;
community_entry_free(entry);
}
@ -267,15 +252,13 @@ community_list_delete (struct community_list *list)
community_list_free(list);
}
static int
community_list_empty_p (struct community_list *list)
static int community_list_empty_p(struct community_list *list)
{
return (list->head == NULL && list->tail == NULL) ? 1 : 0;
}
/* Add community-list entry to the list. */
static void
community_list_entry_add (struct community_list *list,
static void community_list_entry_add(struct community_list *list,
struct community_entry *entry)
{
entry->next = NULL;
@ -289,9 +272,9 @@ community_list_entry_add (struct community_list *list,
}
/* Delete community-list entry from the list. */
static void
community_list_entry_delete (struct community_list *list,
struct community_entry *entry, int style)
static void community_list_entry_delete(struct community_list *list,
struct community_entry *entry,
int style)
{
if (entry->next)
entry->next->prev = entry->prev;
@ -316,26 +299,28 @@ community_list_entry_lookup (struct community_list *list, const void *arg,
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
switch (entry->style)
{
for (entry = list->head; entry; entry = entry->next) {
switch (entry->style) {
case COMMUNITY_LIST_STANDARD:
if (entry->direct == direct && community_cmp (entry->u.com, arg))
if (entry->direct == direct
&& community_cmp(entry->u.com, arg))
return entry;
break;
case EXTCOMMUNITY_LIST_STANDARD:
if (entry->direct == direct && ecommunity_cmp (entry->u.ecom, arg))
if (entry->direct == direct
&& ecommunity_cmp(entry->u.ecom, arg))
return entry;
break;
case LARGE_COMMUNITY_LIST_STANDARD:
if (entry->direct == direct && lcommunity_cmp (entry->u.lcom, arg))
if (entry->direct == direct
&& lcommunity_cmp(entry->u.lcom, arg))
return entry;
break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
case LARGE_COMMUNITY_LIST_EXPANDED:
if (entry->direct == direct && strcmp (entry->config, arg) == 0)
if (entry->direct == direct
&& strcmp(entry->config, arg) == 0)
return entry;
break;
default:
@ -345,8 +330,7 @@ community_list_entry_lookup (struct community_list *list, const void *arg,
return NULL;
}
static char *
community_str_get (struct community *com, int i)
static char *community_str_get(struct community *com, int i)
{
int len;
u_int32_t comval;
@ -358,8 +342,7 @@ community_str_get (struct community *com, int i)
memcpy(&comval, com_nthval(com, i), sizeof(u_int32_t));
comval = ntohl(comval);
switch (comval)
{
switch (comval) {
case COMMUNITY_INTERNET:
len = strlen(" internet");
break;
@ -380,8 +363,7 @@ community_str_get (struct community *com, int i)
/* Allocate memory. */
str = pnt = XMALLOC(MTYPE_COMMUNITY_STR, len);
switch (comval)
{
switch (comval) {
case COMMUNITY_INTERNET:
strcpy(pnt, "internet");
pnt += strlen("internet");
@ -413,13 +395,13 @@ community_str_get (struct community *com, int i)
/* Internal function to perform regular expression match for
* a single community. */
static int
community_regexp_include (regex_t * reg, struct community *com, int i)
static int community_regexp_include(regex_t *reg, struct community *com, int i)
{
char *str;
int rv;
/* When there is no communities attribute it is treated as empty string. */
/* When there is no communities attribute it is treated as empty string.
*/
if (com == NULL || com->size == 0)
str = XSTRDUP(MTYPE_COMMUNITY_STR, "");
else
@ -439,8 +421,7 @@ community_regexp_include (regex_t * reg, struct community *com, int i)
/* Internal function to perform regular expression match for community
attribute. */
static int
community_regexp_match (struct community *com, regex_t * reg)
static int community_regexp_match(struct community *com, regex_t *reg)
{
const char *str;
@ -459,8 +440,7 @@ community_regexp_match (struct community *com, regex_t * reg)
return 0;
}
static char *
lcommunity_str_get (struct lcommunity *lcom, int i)
static char *lcommunity_str_get(struct lcommunity *lcom, int i)
{
struct lcommunity_val lcomval;
u_int32_t globaladmin;
@ -503,20 +483,20 @@ lcommunity_str_get (struct lcommunity *lcom, int i)
/* Internal function to perform regular expression match for
* a single community. */
static int
lcommunity_regexp_include (regex_t * reg, struct lcommunity *lcom, int i)
static int lcommunity_regexp_include(regex_t *reg, struct lcommunity *lcom,
int i)
{
char *str;
/* When there is no communities attribute it is treated as empty string. */
/* When there is no communities attribute it is treated as empty string.
*/
if (lcom == NULL || lcom->size == 0)
str = XSTRDUP(MTYPE_LCOMMUNITY_STR, "");
else
str = lcommunity_str_get(lcom, i);
/* Regular expression match. */
if (regexec (reg, str, 0, NULL, 0) == 0)
{
if (regexec(reg, str, 0, NULL, 0) == 0) {
XFREE(MTYPE_LCOMMUNITY_STR, str);
return 1;
}
@ -526,8 +506,7 @@ lcommunity_regexp_include (regex_t * reg, struct lcommunity *lcom, int i)
return 0;
}
static int
lcommunity_regexp_match (struct lcommunity *com, regex_t * reg)
static int lcommunity_regexp_match(struct lcommunity *com, regex_t *reg)
{
const char *str;
@ -547,8 +526,7 @@ lcommunity_regexp_match (struct lcommunity *com, regex_t * reg)
}
static int
ecommunity_regexp_match (struct ecommunity *ecom, regex_t * reg)
static int ecommunity_regexp_match(struct ecommunity *ecom, regex_t *reg)
{
const char *str;
@ -619,76 +597,68 @@ community_regexp_delete (struct community *com, regex_t * reg)
/* When given community attribute matches to the community-list return
1 else return 0. */
int
community_list_match (struct community *com, struct community_list *list)
int community_list_match(struct community *com, struct community_list *list)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
for (entry = list->head; entry; entry = entry->next) {
if (entry->any)
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (entry->style == COMMUNITY_LIST_STANDARD)
{
if (entry->style == COMMUNITY_LIST_STANDARD) {
if (community_include(entry->u.com, COMMUNITY_INTERNET))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
if (community_match(com, entry->u.com))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
else if (entry->style == COMMUNITY_LIST_EXPANDED)
{
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
} else if (entry->style == COMMUNITY_LIST_EXPANDED) {
if (community_regexp_match(com, entry->reg))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
}
}
return 0;
}
int
lcommunity_list_match (struct lcommunity *lcom, struct community_list *list)
int lcommunity_list_match(struct lcommunity *lcom, struct community_list *list)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
for (entry = list->head; entry; entry = entry->next) {
if (entry->any)
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (entry->style == LARGE_COMMUNITY_LIST_STANDARD)
{
if (entry->style == LARGE_COMMUNITY_LIST_STANDARD) {
if (lcommunity_match(lcom, entry->u.lcom))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
else if (entry->style == LARGE_COMMUNITY_LIST_EXPANDED)
{
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
} else if (entry->style == LARGE_COMMUNITY_LIST_EXPANDED) {
if (lcommunity_regexp_match(lcom, entry->reg))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
}
}
return 0;
}
int
ecommunity_list_match (struct ecommunity *ecom, struct community_list *list)
int ecommunity_list_match(struct ecommunity *ecom, struct community_list *list)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
for (entry = list->head; entry; entry = entry->next) {
if (entry->any)
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (entry->style == EXTCOMMUNITY_LIST_STANDARD)
{
if (entry->style == EXTCOMMUNITY_LIST_STANDARD) {
if (ecommunity_match(ecom, entry->u.ecom))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
else if (entry->style == EXTCOMMUNITY_LIST_EXPANDED)
{
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
} else if (entry->style == EXTCOMMUNITY_LIST_EXPANDED) {
if (ecommunity_regexp_match(ecom, entry->reg))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
}
}
return 0;
@ -696,37 +666,34 @@ ecommunity_list_match (struct ecommunity *ecom, struct community_list *list)
/* Perform exact matching. In case of expanded community-list, do
same thing as community_list_match(). */
int
community_list_exact_match (struct community *com,
int community_list_exact_match(struct community *com,
struct community_list *list)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
for (entry = list->head; entry; entry = entry->next) {
if (entry->any)
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (entry->style == COMMUNITY_LIST_STANDARD)
{
if (entry->style == COMMUNITY_LIST_STANDARD) {
if (community_include(entry->u.com, COMMUNITY_INTERNET))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
if (community_cmp(com, entry->u.com))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
else if (entry->style == COMMUNITY_LIST_EXPANDED)
{
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
} else if (entry->style == COMMUNITY_LIST_EXPANDED) {
if (community_regexp_match(com, entry->reg))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
return entry->direct == COMMUNITY_PERMIT ? 1
: 0;
}
}
return 0;
}
/* Delete all permitted communities in the list from com. */
struct community *
community_list_match_delete (struct community *com,
struct community *community_list_match_delete(struct community *com,
struct community_list *list)
{
struct community_entry *entry;
@ -736,19 +703,16 @@ community_list_match_delete (struct community *com,
int i;
/* Loop over each community value and evaluate each against the
* community-list. If we need to delete a community value add its index to
* community-list. If we need to delete a community value add its index
* to
* com_index_to_delete.
*/
for (i = 0; i < com->size; i++)
{
for (i = 0; i < com->size; i++) {
val = community_val_get(com, i);
for (entry = list->head; entry; entry = entry->next)
{
if (entry->any)
{
if (entry->direct == COMMUNITY_PERMIT)
{
for (entry = list->head; entry; entry = entry->next) {
if (entry->any) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
@ -756,11 +720,10 @@ community_list_match_delete (struct community *com,
}
else if ((entry->style == COMMUNITY_LIST_STANDARD)
&& (community_include (entry->u.com, COMMUNITY_INTERNET)
|| community_include (entry->u.com, val) ))
{
if (entry->direct == COMMUNITY_PERMIT)
{
&& (community_include(entry->u.com,
COMMUNITY_INTERNET)
|| community_include(entry->u.com, val))) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
@ -768,10 +731,9 @@ community_list_match_delete (struct community *com,
}
else if ((entry->style == COMMUNITY_LIST_EXPANDED)
&& community_regexp_include (entry->reg, com, i))
{
if (entry->direct == COMMUNITY_PERMIT)
{
&& community_regexp_include(entry->reg, com,
i)) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
@ -781,8 +743,7 @@ community_list_match_delete (struct community *com,
}
/* Delete all of the communities we flagged for deletion */
for (i = delete_index-1; i >= 0; i--)
{
for (i = delete_index - 1; i >= 0; i--) {
val = community_val_get(com, com_index_to_delete[i]);
community_del_val(com, &val);
}
@ -792,14 +753,12 @@ community_list_match_delete (struct community *com,
/* To avoid duplicated entry in the community-list, this function
compares specified entry to existing entry. */
static int
community_list_dup_check (struct community_list *list,
static int community_list_dup_check(struct community_list *list,
struct community_entry *new)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
for (entry = list->head; entry; entry = entry->next) {
if (entry->style != new->style)
continue;
@ -812,8 +771,7 @@ community_list_dup_check (struct community_list *list,
if (entry->any)
return 1;
switch (entry->style)
{
switch (entry->style) {
case COMMUNITY_LIST_STANDARD:
if (community_cmp(entry->u.com, new->u.com))
return 1;
@ -840,9 +798,8 @@ community_list_dup_check (struct community_list *list,
}
/* Set community-list. */
int
community_list_set (struct community_list_handler *ch,
const char *name, const char *str, int direct, int style)
int community_list_set(struct community_list_handler *ch, const char *name,
const char *str, int direct, int style)
{
struct community_entry *entry = NULL;
struct community_list *list;
@ -855,22 +812,19 @@ community_list_set (struct community_list_handler *ch,
/* When community-list already has entry, new entry should have same
style. If you want to have mixed style community-list, you can
comment out this check. */
if (!community_list_empty_p (list))
{
if (!community_list_empty_p(list)) {
struct community_entry *first;
first = list->head;
if (style != first->style)
{
if (style != first->style) {
return (first->style == COMMUNITY_LIST_STANDARD
? COMMUNITY_LIST_ERR_STANDARD_CONFLICT
: COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);
}
}
if (str)
{
if (str) {
if (style == COMMUNITY_LIST_STANDARD)
com = community_str2com(str);
else
@ -886,13 +840,13 @@ community_list_set (struct community_list_handler *ch,
entry->any = (str ? 0 : 1);
entry->u.com = com;
entry->reg = regex;
entry->config = (regex ? XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str) : NULL);
entry->config =
(regex ? XSTRDUP(MTYPE_COMMUNITY_LIST_CONFIG, str) : NULL);
/* Do not put duplicated community entry. */
if (community_list_dup_check(list, entry))
community_entry_free(entry);
else
{
else {
community_list_entry_add(list, entry);
route_map_notify_dependencies(name, RMAP_EVENT_CLIST_ADDED);
}
@ -901,10 +855,8 @@ community_list_set (struct community_list_handler *ch,
}
/* Unset community-list */
int
community_list_unset (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style, int delete_all)
int community_list_unset(struct community_list_handler *ch, const char *name,
const char *str, int direct, int style, int delete_all)
{
struct community_entry *entry = NULL;
struct community_list *list;
@ -916,25 +868,21 @@ community_list_unset (struct community_list_handler *ch,
return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
/* Delete all of entry belongs to this community-list. */
if (delete_all)
{
if (delete_all) {
community_list_delete(list);
route_map_notify_dependencies(name, RMAP_EVENT_CLIST_DELETED);
return 0;
}
if (style == COMMUNITY_LIST_STANDARD)
{
if (style == COMMUNITY_LIST_STANDARD) {
if (str)
com = community_str2com(str);
}
if (com)
{
if (com) {
entry = community_list_entry_lookup(list, com, direct);
community_free(com);
}
else
} else
entry = community_list_entry_lookup(list, str, direct);
if (!entry)
@ -947,8 +895,7 @@ community_list_unset (struct community_list_handler *ch,
}
/* Delete all permitted large communities in the list from com. */
struct lcommunity *
lcommunity_list_match_delete (struct lcommunity *lcom,
struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
struct community_list *list)
{
struct community_entry *entry;
@ -958,19 +905,16 @@ lcommunity_list_match_delete (struct lcommunity *lcom,
int i;
/* Loop over each lcommunity value and evaluate each against the
* community-list. If we need to delete a community value add its index to
* community-list. If we need to delete a community value add its index
* to
* com_index_to_delete.
*/
ptr = lcom->val;
for (i = 0; i < lcom->size; i++)
{
for (i = 0; i < lcom->size; i++) {
ptr += (i * LCOMMUNITY_SIZE);
for (entry = list->head; entry; entry = entry->next)
{
if (entry->any)
{
if (entry->direct == COMMUNITY_PERMIT)
{
for (entry = list->head; entry; entry = entry->next) {
if (entry->any) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
@ -978,10 +922,8 @@ lcommunity_list_match_delete (struct lcommunity *lcom,
}
else if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD)
&& lcommunity_include (entry->u.lcom, ptr) )
{
if (entry->direct == COMMUNITY_PERMIT)
{
&& lcommunity_include(entry->u.lcom, ptr)) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
@ -989,10 +931,9 @@ lcommunity_list_match_delete (struct lcommunity *lcom,
}
else if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD)
&& lcommunity_regexp_include (entry->reg, lcom, i))
{
if (entry->direct == COMMUNITY_PERMIT)
{
&& lcommunity_regexp_include(entry->reg, lcom,
i)) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
@ -1003,8 +944,7 @@ lcommunity_list_match_delete (struct lcommunity *lcom,
/* Delete all of the communities we flagged for deletion */
ptr = lcom->val;
for (i = delete_index-1; i >= 0; i--)
{
for (i = delete_index - 1; i >= 0; i--) {
ptr += (com_index_to_delete[i] * LCOMMUNITY_SIZE);
lcommunity_del_val(lcom, ptr);
}
@ -1013,9 +953,8 @@ lcommunity_list_match_delete (struct lcommunity *lcom,
}
/* Set lcommunity-list. */
int
lcommunity_list_set (struct community_list_handler *ch,
const char *name, const char *str, int direct, int style)
int lcommunity_list_set(struct community_list_handler *ch, const char *name,
const char *str, int direct, int style)
{
struct community_entry *entry = NULL;
struct community_list *list;
@ -1028,22 +967,19 @@ lcommunity_list_set (struct community_list_handler *ch,
/* When community-list already has entry, new entry should have same
style. If you want to have mixed style community-list, you can
comment out this check. */
if (!community_list_empty_p (list))
{
if (!community_list_empty_p(list)) {
struct community_entry *first;
first = list->head;
if (style != first->style)
{
if (style != first->style) {
return (first->style == COMMUNITY_LIST_STANDARD
? COMMUNITY_LIST_ERR_STANDARD_CONFLICT
: COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);
}
}
if (str)
{
if (str) {
if (style == LARGE_COMMUNITY_LIST_STANDARD)
lcom = lcommunity_str2com(str);
else
@ -1060,7 +996,8 @@ lcommunity_list_set (struct community_list_handler *ch,
entry->u.lcom = lcom;
entry->reg = regex;
if (lcom)
entry->config = lcommunity_lcom2str (lcom, LCOMMUNITY_FORMAT_COMMUNITY_LIST);
entry->config = lcommunity_lcom2str(
lcom, LCOMMUNITY_FORMAT_COMMUNITY_LIST);
else if (regex)
entry->config = XSTRDUP(MTYPE_COMMUNITY_LIST_CONFIG, str);
else
@ -1077,10 +1014,8 @@ lcommunity_list_set (struct community_list_handler *ch,
/* Unset community-list. When str is NULL, delete all of
community-list entry belongs to the specified name. */
int
lcommunity_list_unset (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style)
int lcommunity_list_unset(struct community_list_handler *ch, const char *name,
const char *str, int direct, int style)
{
struct community_entry *entry = NULL;
struct community_list *list;
@ -1093,8 +1028,7 @@ lcommunity_list_unset (struct community_list_handler *ch,
return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
/* Delete all of entry belongs to this community-list. */
if (!str)
{
if (!str) {
community_list_delete(list);
return 0;
}
@ -1126,10 +1060,8 @@ lcommunity_list_unset (struct community_list_handler *ch,
}
/* Set extcommunity-list. */
int
extcommunity_list_set (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style)
int extcommunity_list_set(struct community_list_handler *ch, const char *name,
const char *str, int direct, int style)
{
struct community_entry *entry = NULL;
struct community_list *list;
@ -1144,14 +1076,12 @@ extcommunity_list_set (struct community_list_handler *ch,
/* When community-list already has entry, new entry should have same
style. If you want to have mixed style community-list, you can
comment out this check. */
if (!community_list_empty_p (list))
{
if (!community_list_empty_p(list)) {
struct community_entry *first;
first = list->head;
if (style != first->style)
{
if (style != first->style) {
return (first->style == EXTCOMMUNITY_LIST_STANDARD
? COMMUNITY_LIST_ERR_STANDARD_CONFLICT
: COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);
@ -1167,14 +1097,16 @@ extcommunity_list_set (struct community_list_handler *ch,
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
if (ecom)
ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
ecom->str =
ecommunity_ecom2str(ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
entry = community_entry_new();
entry->direct = direct;
entry->style = style;
entry->any = (str ? 0 : 1);
if (ecom)
entry->config = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0);
entry->config = ecommunity_ecom2str(
ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0);
else if (regex)
entry->config = XSTRDUP(MTYPE_COMMUNITY_LIST_CONFIG, str);
@ -1184,8 +1116,7 @@ extcommunity_list_set (struct community_list_handler *ch,
/* Do not put duplicated community entry. */
if (community_list_dup_check(list, entry))
community_entry_free(entry);
else
{
else {
community_list_entry_add(list, entry);
route_map_notify_dependencies(name, RMAP_EVENT_ECLIST_ADDED);
}
@ -1195,10 +1126,9 @@ extcommunity_list_set (struct community_list_handler *ch,
/* Unset extcommunity-list. When str is NULL, delete all of
extcommunity-list entry belongs to the specified name. */
int
extcommunity_list_unset (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style, int delete_all)
int extcommunity_list_unset(struct community_list_handler *ch, const char *name,
const char *str, int direct, int style,
int delete_all)
{
struct community_entry *entry = NULL;
struct community_list *list;
@ -1210,25 +1140,21 @@ extcommunity_list_unset (struct community_list_handler *ch,
return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
/* Delete all of entry belongs to this extcommunity-list. */
if (delete_all)
{
if (delete_all) {
community_list_delete(list);
route_map_notify_dependencies(name, RMAP_EVENT_ECLIST_DELETED);
return 0;
}
if (style == EXTCOMMUNITY_LIST_STANDARD)
{
if (style == EXTCOMMUNITY_LIST_STANDARD) {
if (str)
ecom = ecommunity_str2com(str, 0, 1);
}
if (ecom)
{
if (ecom) {
entry = community_list_entry_lookup(list, ecom, direct);
ecommunity_free(&ecom);
}
else
} else
entry = community_list_entry_lookup(list, str, direct);
if (!entry)
@ -1241,8 +1167,7 @@ extcommunity_list_unset (struct community_list_handler *ch,
}
/* Initializa community-list. Return community-list handler. */
struct community_list_handler *
community_list_init (void)
struct community_list_handler *community_list_init(void)
{
struct community_list_handler *ch;
ch = XCALLOC(MTYPE_COMMUNITY_LIST_HANDLER,
@ -1251,8 +1176,7 @@ community_list_init (void)
}
/* Terminate community-list. */
void
community_list_terminate (struct community_list_handler *ch)
void community_list_terminate(struct community_list_handler *ch)
{
struct community_list_master *cm;
struct community_list *list;

View File

@ -43,8 +43,7 @@
#define LARGE_COMMUNITY_LIST_EXPANDED 5 /* Expanded Large community-list. */
/* Community-list. */
struct community_list
{
struct community_list {
/* Name of the community-list. */
char *name;
@ -64,8 +63,7 @@ struct community_list
};
/* Each entry in community-list. */
struct community_entry
{
struct community_entry {
struct community_entry *next;
struct community_entry *prev;
@ -79,8 +77,7 @@ struct community_entry
u_char any;
/* Community structure. */
union
{
union {
struct community *com;
struct ecommunity *ecom;
struct lcommunity *lcom;
@ -94,23 +91,20 @@ struct community_entry
};
/* Linked list of community-list. */
struct community_list_list
{
struct community_list_list {
struct community_list *head;
struct community_list *tail;
};
/* Master structure of community-list and extcommunity-list. */
struct community_list_master
{
struct community_list_master {
struct community_list_list num;
struct community_list_list str;
};
/* Community-list handler. community_list_init() returns this
structure as handler. */
struct community_list_handler
{
struct community_list_handler {
/* Community-list. */
struct community_list_master community_list;
@ -138,20 +132,20 @@ extern int community_list_set (struct community_list_handler *ch,
const char *name, const char *str, int direct,
int style);
extern int community_list_unset(struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style, int delete_all);
const char *name, const char *str, int direct,
int style, int delete_all);
extern int extcommunity_list_set(struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style);
const char *name, const char *str, int direct,
int style);
extern int extcommunity_list_unset(struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style, int delete_all);
extern int lcommunity_list_set(struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style);
const char *name, const char *str, int direct,
int style);
extern int lcommunity_list_unset(struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style);
const char *name, const char *str, int direct,
int style);
extern struct community_list_master *
community_list_master_lookup(struct community_list_handler *, int);
@ -164,8 +158,8 @@ extern int ecommunity_list_match (struct ecommunity *, struct community_list *);
extern int lcommunity_list_match(struct lcommunity *, struct community_list *);
extern int community_list_exact_match(struct community *,
struct community_list *);
extern struct community *
community_list_match_delete (struct community *, struct community_list *);
extern struct community *community_list_match_delete(struct community *,
struct community_list *);
extern struct lcommunity *
lcommunity_list_match_delete(struct lcommunity *lcom,
struct community_list *list);

View File

@ -31,24 +31,21 @@
static struct hash *comhash;
/* Allocate a new communities value. */
static struct community *
community_new (void)
static struct community *community_new(void)
{
return (struct community *)XCALLOC(MTYPE_COMMUNITY,
sizeof(struct community));
}
/* Free communities value. */
void
community_free (struct community *com)
void community_free(struct community *com)
{
if (com->val)
XFREE(MTYPE_COMMUNITY_VAL, com->val);
if (com->str)
XFREE(MTYPE_COMMUNITY_STR, com->str);
if (com->json)
{
if (com->json) {
json_object_free(com->json);
com->json = NULL;
}
@ -57,12 +54,12 @@ community_free (struct community *com)
}
/* Add one community value to the community. */
static void
community_add_val (struct community *com, u_int32_t val)
static void community_add_val(struct community *com, u_int32_t val)
{
com->size++;
if (com->val)
com->val = XREALLOC (MTYPE_COMMUNITY_VAL, com->val, com_length (com));
com->val = XREALLOC(MTYPE_COMMUNITY_VAL, com->val,
com_length(com));
else
com->val = XMALLOC(MTYPE_COMMUNITY_VAL, com_length(com));
@ -71,8 +68,7 @@ community_add_val (struct community *com, u_int32_t val)
}
/* Delete one community. */
void
community_del_val (struct community *com, u_int32_t *val)
void community_del_val(struct community *com, u_int32_t *val)
{
int i = 0;
int c = 0;
@ -80,22 +76,20 @@ community_del_val (struct community *com, u_int32_t *val)
if (!com->val)
return;
while (i < com->size)
{
if (memcmp (com->val + i, val, sizeof (u_int32_t)) == 0)
{
while (i < com->size) {
if (memcmp(com->val + i, val, sizeof(u_int32_t)) == 0) {
c = com->size - i - 1;
if (c > 0)
memmove (com->val + i, com->val + (i + 1), c * sizeof (*val));
memmove(com->val + i, com->val + (i + 1),
c * sizeof(*val));
com->size--;
if (com->size > 0)
com->val = XREALLOC (MTYPE_COMMUNITY_VAL, com->val,
com_length (com));
else
{
com->val = XREALLOC(MTYPE_COMMUNITY_VAL,
com->val, com_length(com));
else {
XFREE(MTYPE_COMMUNITY_VAL, com->val);
com->val = NULL;
}
@ -106,13 +100,12 @@ community_del_val (struct community *com, u_int32_t *val)
}
/* Delete all communities listed in com2 from com1 */
struct community *
community_delete (struct community *com1, struct community *com2)
struct community *community_delete(struct community *com1,
struct community *com2)
{
int i = 0;
while(i < com2->size)
{
while (i < com2->size) {
community_del_val(com1, com2->val + i);
i++;
}
@ -121,8 +114,7 @@ community_delete (struct community *com1, struct community *com2)
}
/* Callback function from qsort(). */
static int
community_compare (const void *a1, const void *a2)
static int community_compare(const void *a1, const void *a2)
{
u_int32_t v1;
u_int32_t v2;
@ -139,8 +131,7 @@ community_compare (const void *a1, const void *a2)
return 0;
}
int
community_include (struct community *com, u_int32_t val)
int community_include(struct community *com, u_int32_t val)
{
int i;
@ -153,8 +144,7 @@ community_include (struct community *com, u_int32_t val)
return 0;
}
u_int32_t
community_val_get (struct community *com, int i)
u_int32_t community_val_get(struct community *com, int i)
{
u_char *p;
u_int32_t val;
@ -168,8 +158,7 @@ community_val_get (struct community *com, int i)
}
/* Sort and uniq given community. */
struct community *
community_uniq_sort (struct community *com)
struct community *community_uniq_sort(struct community *com)
{
int i;
struct community *new;
@ -178,11 +167,11 @@ community_uniq_sort (struct community *com)
if (!com)
return NULL;
new = community_new ();;
new = community_new();
;
new->json = NULL;
for (i = 0; i < com->size; i++)
{
for (i = 0; i < com->size; i++) {
val = community_val_get(com, i);
if (!community_include(new, val))
@ -204,8 +193,7 @@ community_uniq_sort (struct community *com)
0xFFFFFF03 "local-AS"
For other values, "AS:VAL" format is used. */
static void
set_community_string (struct community *com)
static void set_community_string(struct community *com)
{
int i;
char *str;
@ -225,8 +213,7 @@ set_community_string (struct community *com)
json_community_list = json_object_new_array();
/* When communities attribute is empty. */
if (com->size == 0)
{
if (com->size == 0) {
str = XMALLOC(MTYPE_COMMUNITY_STR, 1);
str[0] = '\0';
@ -240,13 +227,11 @@ set_community_string (struct community *com)
required string length first. */
len = 0;
for (i = 0; i < com->size; i++)
{
for (i = 0; i < com->size; i++) {
memcpy(&comval, com_nthval(com, i), sizeof(u_int32_t));
comval = ntohl(comval);
switch (comval)
{
switch (comval) {
case COMMUNITY_INTERNET:
len += strlen(" internet");
break;
@ -270,8 +255,7 @@ set_community_string (struct community *com)
first = 1;
/* Fill in string. */
for (i = 0; i < com->size; i++)
{
for (i = 0; i < com->size; i++) {
memcpy(&comval, com_nthval(com, i), sizeof(u_int32_t));
comval = ntohl(comval);
@ -280,8 +264,7 @@ set_community_string (struct community *com)
else
*pnt++ = ' ';
switch (comval)
{
switch (comval) {
case COMMUNITY_INTERNET:
strcpy(pnt, "internet");
pnt += strlen("internet");
@ -324,8 +307,7 @@ set_community_string (struct community *com)
}
/* Intern communities attribute. */
struct community *
community_intern (struct community *com)
struct community *community_intern(struct community *com)
{
struct community *find;
@ -351,8 +333,7 @@ community_intern (struct community *com)
}
/* Free community attribute. */
void
community_unintern (struct community **com)
void community_unintern(struct community **com)
{
struct community *ret;
@ -360,8 +341,7 @@ community_unintern (struct community **com)
(*com)->refcnt--;
/* Pull off from hash. */
if ((*com)->refcnt == 0)
{
if ((*com)->refcnt == 0) {
/* Community value com must exist in hash. */
ret = (struct community *)hash_release(comhash, *com);
assert(ret != NULL);
@ -372,8 +352,7 @@ community_unintern (struct community **com)
}
/* Create new community attribute. */
struct community *
community_parse (u_int32_t *pnt, u_short length)
struct community *community_parse(u_int32_t *pnt, u_short length)
{
struct community tmp;
struct community *new;
@ -391,26 +370,22 @@ community_parse (u_int32_t *pnt, u_short length)
return community_intern(new);
}
struct community *
community_dup (struct community *com)
struct community *community_dup(struct community *com)
{
struct community *new;
new = XCALLOC(MTYPE_COMMUNITY, sizeof(struct community));
new->size = com->size;
if (new->size)
{
if (new->size) {
new->val = XMALLOC(MTYPE_COMMUNITY_VAL, com->size * 4);
memcpy(new->val, com->val, com->size * 4);
}
else
} else
new->val = NULL;
return new;
}
/* Retrun string representation of communities attribute. */
char *
community_str (struct community *com)
char *community_str(struct community *com)
{
if (!com)
return NULL;
@ -422,16 +397,14 @@ community_str (struct community *com)
/* Make hash value of community attribute. This function is used by
hash package.*/
unsigned int
community_hash_make (struct community *com)
unsigned int community_hash_make(struct community *com)
{
unsigned char *pnt = (unsigned char *)com->val;
int size = com->size * 4;
unsigned int key = 0;
int c;
for (c = 0; c < size; c += 4)
{
for (c = 0; c < size; c += 4) {
key += pnt[c];
key += pnt[c + 1];
key += pnt[c + 2];
@ -441,8 +414,7 @@ community_hash_make (struct community *com)
return key;
}
int
community_match (const struct community *com1, const struct community *com2)
int community_match(const struct community *com1, const struct community *com2)
{
int i = 0;
int j = 0;
@ -457,9 +429,9 @@ community_match (const struct community *com1, const struct community *com2)
return 0;
/* Every community on com2 needs to be on com1 for this to match */
while (i < com1->size && j < com2->size)
{
if (memcmp (com1->val + i, com2->val + j, sizeof (u_int32_t)) == 0)
while (i < com1->size && j < com2->size) {
if (memcmp(com1->val + i, com2->val + j, sizeof(u_int32_t))
== 0)
j++;
i++;
}
@ -472,8 +444,7 @@ community_match (const struct community *com1, const struct community *com2)
/* If two aspath have same value then return 1 else return 0. This
function is used by hash package. */
int
community_cmp (const struct community *com1, const struct community *com2)
int community_cmp(const struct community *com1, const struct community *com2)
{
if (com1 == NULL && com2 == NULL)
return 1;
@ -487,14 +458,15 @@ community_cmp (const struct community *com1, const struct community *com2)
}
/* Add com2 to the end of com1. */
struct community *
community_merge (struct community *com1, struct community *com2)
struct community *community_merge(struct community *com1,
struct community *com2)
{
if (com1->val)
com1->val = XREALLOC(MTYPE_COMMUNITY_VAL, com1->val,
(com1->size + com2->size) * 4);
else
com1->val = XMALLOC (MTYPE_COMMUNITY_VAL, (com1->size + com2->size) * 4);
com1->val = XMALLOC(MTYPE_COMMUNITY_VAL,
(com1->size + com2->size) * 4);
memcpy(com1->val + com1->size, com2->val, com2->size * 4);
com1->size += com2->size;
@ -503,8 +475,7 @@ community_merge (struct community *com1, struct community *com2)
}
/* Community token enum. */
enum community_token
{
enum community_token {
community_token_val,
community_token_no_export,
community_token_no_advertise,
@ -514,8 +485,7 @@ enum community_token
/* Get next community token from string. */
static const char *
community_gettoken (const char *buf, enum community_token *token,
u_int32_t *val)
community_gettoken(const char *buf, enum community_token *token, u_int32_t *val)
{
const char *p = buf;
@ -528,31 +498,26 @@ community_gettoken (const char *buf, enum community_token *token,
return NULL;
/* Well known community string check. */
if (isalpha ((int) *p))
{
if (strncmp (p, "internet", strlen ("internet")) == 0)
{
if (isalpha((int)*p)) {
if (strncmp(p, "internet", strlen("internet")) == 0) {
*val = COMMUNITY_INTERNET;
*token = community_token_no_export;
p += strlen("internet");
return p;
}
if (strncmp (p, "no-export", strlen ("no-export")) == 0)
{
if (strncmp(p, "no-export", strlen("no-export")) == 0) {
*val = COMMUNITY_NO_EXPORT;
*token = community_token_no_export;
p += strlen("no-export");
return p;
}
if (strncmp (p, "no-advertise", strlen ("no-advertise")) == 0)
{
if (strncmp(p, "no-advertise", strlen("no-advertise")) == 0) {
*val = COMMUNITY_NO_ADVERTISE;
*token = community_token_no_advertise;
p += strlen("no-advertise");
return p;
}
if (strncmp (p, "local-AS", strlen ("local-AS")) == 0)
{
if (strncmp(p, "local-AS", strlen("local-AS")) == 0) {
*val = COMMUNITY_LOCAL_AS;
*token = community_token_local_as;
p += strlen("local-AS");
@ -565,53 +530,43 @@ community_gettoken (const char *buf, enum community_token *token,
}
/* Community value. */
if (isdigit ((int) *p))
{
if (isdigit((int)*p)) {
int separator = 0;
int digit = 0;
u_int32_t community_low = 0;
u_int32_t community_high = 0;
while (isdigit ((int) *p) || *p == ':')
{
if (*p == ':')
{
if (separator)
{
while (isdigit((int)*p) || *p == ':') {
if (*p == ':') {
if (separator) {
*token = community_token_unknown;
return NULL;
}
else
{
} else {
separator = 1;
digit = 0;
if (community_low > UINT16_MAX)
{
*token = community_token_unknown;
if (community_low > UINT16_MAX) {
*token =
community_token_unknown;
return NULL;
}
community_high = community_low << 16;
community_low = 0;
}
}
else
{
} else {
digit = 1;
community_low *= 10;
community_low += (*p - '0');
}
p++;
}
if (! digit)
{
if (!digit) {
*token = community_token_unknown;
return NULL;
}
if (community_low > UINT16_MAX)
{
if (community_low > UINT16_MAX) {
*token = community_token_unknown;
return NULL;
}
@ -625,26 +580,22 @@ community_gettoken (const char *buf, enum community_token *token,
}
/* convert string to community structure */
struct community *
community_str2com (const char *str)
struct community *community_str2com(const char *str)
{
struct community *com = NULL;
struct community *com_sort = NULL;
u_int32_t val = 0;
enum community_token token = community_token_unknown;
do
{
do {
str = community_gettoken(str, &token, &val);
switch (token)
{
switch (token) {
case community_token_val:
case community_token_no_export:
case community_token_no_advertise:
case community_token_local_as:
if (com == NULL)
{
if (com == NULL) {
com = community_new();
com->json = NULL;
}
@ -668,29 +619,26 @@ community_str2com (const char *str)
}
/* Return communities hash entry count. */
unsigned long
community_count (void)
unsigned long community_count(void)
{
return comhash->count;
}
/* Return communities hash. */
struct hash *
community_hash (void)
struct hash *community_hash(void)
{
return comhash;
}
/* Initialize comminity related hash. */
void
community_init (void)
void community_init(void)
{
comhash = hash_create ((unsigned int (*) (void *))community_hash_make,
comhash = hash_create(
(unsigned int (*)(void *))community_hash_make,
(int (*)(const void *, const void *))community_cmp, NULL);
}
void
community_finish (void)
void community_finish(void)
{
hash_free(comhash);
comhash = NULL;

View File

@ -24,8 +24,7 @@
#include "lib/json.h"
/* Communities attribute. */
struct community
{
struct community {
/* Reference count of communities value. */
unsigned long refcnt;
@ -68,8 +67,10 @@ extern unsigned int community_hash_make (struct community *);
extern struct community *community_str2com(const char *);
extern int community_match(const struct community *, const struct community *);
extern int community_cmp(const struct community *, const struct community *);
extern struct community *community_merge (struct community *, struct community *);
extern struct community *community_delete (struct community *, struct community *);
extern struct community *community_merge(struct community *,
struct community *);
extern struct community *community_delete(struct community *,
struct community *);
extern struct community *community_dup(struct community *);
extern int community_include(struct community *, u_int32_t);
extern void community_del_val(struct community *, u_int32_t *);

View File

@ -46,13 +46,13 @@ static struct bgp_damp_config *damp = &bgp_damp_cfg;
#define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list)
/* Calculate reuse list index by penalty value. */
static int
bgp_reuse_index (int penalty)
static int bgp_reuse_index(int penalty)
{
unsigned int i;
int index;
i = (int)(((double) penalty / damp->reuse_limit - 1.0) * damp->scale_factor);
i = (int)(((double)penalty / damp->reuse_limit - 1.0)
* damp->scale_factor);
if (i >= damp->reuse_index_size)
i = damp->reuse_index_size - 1;
@ -63,8 +63,7 @@ bgp_reuse_index (int penalty)
}
/* Add BGP dampening information to reuse list. */
static void
bgp_reuse_list_add (struct bgp_damp_info *bdi)
static void bgp_reuse_list_add(struct bgp_damp_info *bdi)
{
int index;
@ -78,8 +77,7 @@ bgp_reuse_list_add (struct bgp_damp_info *bdi)
}
/* Delete BGP dampening information from reuse list. */
static void
bgp_reuse_list_delete (struct bgp_damp_info *bdi)
static void bgp_reuse_list_delete(struct bgp_damp_info *bdi)
{
if (bdi->next)
bdi->next->prev = bdi->prev;
@ -90,8 +88,7 @@ bgp_reuse_list_delete (struct bgp_damp_info *bdi)
}
/* Return decayed penalty value. */
int
bgp_damp_decay (time_t tdiff, int penalty)
int bgp_damp_decay(time_t tdiff, int penalty)
{
unsigned int i;
@ -108,8 +105,7 @@ bgp_damp_decay (time_t tdiff, int penalty)
/* Handler of reuse timer event. Each route in the current reuse-list
is evaluated. RFC2439 Section 4.8.7. */
static int
bgp_reuse_timer (struct thread *t)
static int bgp_reuse_timer(struct thread *t)
{
struct bgp_damp_info *bdi;
struct bgp_damp_info *next;
@ -131,8 +127,7 @@ bgp_reuse_timer (struct thread *t)
damp->reuse_offset = (damp->reuse_offset + 1) % damp->reuse_list_size;
/* 3. if ( the saved list head pointer is non-empty ) */
for (; bdi; bdi = next)
{
for (; bdi; bdi = next) {
struct bgp *bgp = bdi->binfo->peer->bgp;
next = bdi->next;
@ -140,24 +135,26 @@ bgp_reuse_timer (struct thread *t)
/* Set t-diff = t-now - t-updated. */
t_diff = t_now - bdi->t_updated;
/* Set figure-of-merit = figure-of-merit * decay-array-ok [t-diff] */
/* Set figure-of-merit = figure-of-merit * decay-array-ok
* [t-diff] */
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
/* Set t-updated = t-now. */
bdi->t_updated = t_now;
/* if (figure-of-merit < reuse). */
if (bdi->penalty < damp->reuse_limit)
{
if (bdi->penalty < damp->reuse_limit) {
/* Reuse the route. */
bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_DAMPED);
bgp_info_unset_flag(bdi->rn, bdi->binfo,
BGP_INFO_DAMPED);
bdi->suppress_time = 0;
if (bdi->lastrecord == BGP_RECORD_UPDATE)
{
bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_HISTORY);
bgp_aggregate_increment (bgp, &bdi->rn->p, bdi->binfo,
bdi->afi, bdi->safi);
if (bdi->lastrecord == BGP_RECORD_UPDATE) {
bgp_info_unset_flag(bdi->rn, bdi->binfo,
BGP_INFO_HISTORY);
bgp_aggregate_increment(bgp, &bdi->rn->p,
bdi->binfo, bdi->afi,
bdi->safi);
bgp_process(bgp, bdi->rn, bdi->afi, bdi->safi);
}
@ -165,9 +162,9 @@ bgp_reuse_timer (struct thread *t)
bgp_damp_info_free(bdi, 1);
else
BGP_DAMP_LIST_ADD(damp, bdi);
}
else
/* Re-insert into another list (See RFC2439 Section 4.8.6). */
} else
/* Re-insert into another list (See RFC2439 Section
* 4.8.6). */
bgp_reuse_list_add(bdi);
}
@ -175,9 +172,8 @@ bgp_reuse_timer (struct thread *t)
}
/* A route becomes unreachable (RFC2439 Section 4.8.2). */
int
bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
afi_t afi, safi_t safi, int attr_change)
int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
safi_t safi, int attr_change)
{
time_t t_now;
struct bgp_damp_info *bdi = NULL;
@ -189,8 +185,7 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
if (binfo->extra)
bdi = binfo->extra->damp_info;
if (bdi == NULL)
{
if (bdi == NULL) {
/* If there is no previous stability history. */
/* RFC2439 said:
@ -198,10 +193,12 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
2. set figure-of-merit = 1.
3. withdraw the route. */
bdi = XCALLOC (MTYPE_BGP_DAMP_INFO, sizeof (struct bgp_damp_info));
bdi = XCALLOC(MTYPE_BGP_DAMP_INFO,
sizeof(struct bgp_damp_info));
bdi->binfo = binfo;
bdi->rn = rn;
bdi->penalty = (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
bdi->penalty =
(attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
bdi->flap = 1;
bdi->start_time = t_now;
bdi->suppress_time = 0;
@ -210,15 +207,14 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
bdi->safi = safi;
(bgp_info_extra_get(binfo))->damp_info = bdi;
BGP_DAMP_LIST_ADD(damp, bdi);
}
else
{
} else {
last_penalty = bdi->penalty;
/* 1. Set t-diff = t-now - t-updated. */
bdi->penalty =
(bgp_damp_decay(t_now - bdi->t_updated, bdi->penalty)
+ (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY));
+ (attr_change ? DEFAULT_PENALTY / 2
: DEFAULT_PENALTY));
if (bdi->penalty > damp->ceiling)
bdi->penalty = damp->ceiling;
@ -235,11 +231,9 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
bgp_info_set_flag(rn, binfo, BGP_INFO_HISTORY);
/* Remove the route from a reuse list if it is on one. */
if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED))
{
if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)) {
/* If decay rate isn't equal to 0, reinsert brn. */
if (bdi->penalty != last_penalty)
{
if (bdi->penalty != last_penalty) {
bgp_reuse_list_delete(bdi);
bgp_reuse_list_add(bdi);
}
@ -248,8 +242,7 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
/* If not suppressed before, do annonunce this withdraw and
insert into reuse_list. */
if (bdi->penalty >= damp->suppress_value)
{
if (bdi->penalty >= damp->suppress_value) {
bgp_info_set_flag(rn, binfo, BGP_INFO_DAMPED);
bdi->suppress_time = t_now;
BGP_DAMP_LIST_DEL(damp, bdi);
@ -259,9 +252,8 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
return BGP_DAMP_USED;
}
int
bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
afi_t afi, safi_t safi)
int bgp_damp_update(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi,
safi_t safi)
{
time_t t_now;
struct bgp_damp_info *bdi;
@ -280,15 +272,13 @@ bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
&& (bdi->penalty < damp->suppress_value))
status = BGP_DAMP_USED;
else if (CHECK_FLAG(bdi->binfo->flags, BGP_INFO_DAMPED)
&& (bdi->penalty < damp->reuse_limit) )
{
&& (bdi->penalty < damp->reuse_limit)) {
bgp_info_unset_flag(rn, binfo, BGP_INFO_DAMPED);
bgp_reuse_list_delete(bdi);
BGP_DAMP_LIST_ADD(damp, bdi);
bdi->suppress_time = 0;
status = BGP_DAMP_USED;
}
else
} else
status = BGP_DAMP_SUPPRESSED;
if (bdi->penalty > damp->reuse_limit / 2.0)
@ -300,8 +290,7 @@ bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
}
/* Remove dampening information and history route. */
int
bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi)
int bgp_damp_scan(struct bgp_info *binfo, afi_t afi, safi_t safi)
{
time_t t_now, t_diff;
struct bgp_damp_info *bdi;
@ -311,12 +300,10 @@ bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi)
t_now = bgp_clock();
bdi = binfo->extra->damp_info;
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
{
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
t_diff = t_now - bdi->suppress_time;
if (t_diff >= damp->max_suppress_time)
{
if (t_diff >= damp->max_suppress_time) {
bgp_info_unset_flag(bdi->rn, binfo, BGP_INFO_DAMPED);
bgp_reuse_list_delete(bdi);
BGP_DAMP_LIST_ADD(damp, bdi);
@ -324,32 +311,28 @@ bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi)
bdi->suppress_time = 0;
bdi->t_updated = t_now;
/* Need to announce UPDATE once this binfo is usable again. */
/* Need to announce UPDATE once this binfo is usable
* again. */
if (bdi->lastrecord == BGP_RECORD_UPDATE)
return 1;
else
return 0;
}
}
else
{
} else {
t_diff = t_now - bdi->t_updated;
bdi->penalty = bgp_damp_decay(t_diff, bdi->penalty);
if (bdi->penalty <= damp->reuse_limit / 2.0)
{
if (bdi->penalty <= damp->reuse_limit / 2.0) {
/* release the bdi, bdi->binfo. */
bgp_damp_info_free(bdi, 1);
return 0;
}
else
} else
bdi->t_updated = t_now;
}
return 0;
}
void
bgp_damp_info_free (struct bgp_damp_info *bdi, int withdraw)
void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw)
{
struct bgp_info *binfo;
@ -372,8 +355,7 @@ bgp_damp_info_free (struct bgp_damp_info *bdi, int withdraw)
XFREE(MTYPE_BGP_DAMP_INFO, bdi);
}
static void
bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup)
{
double reuse_max_ratio;
unsigned int i;
@ -387,18 +369,24 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
/* Initialize params per bgp_damp_config. */
damp->reuse_index_size = REUSE_ARRAY_SIZE;
damp->ceiling = (int)(damp->reuse_limit * (pow(2, (double)damp->max_suppress_time/damp->half_life)));
damp->ceiling =
(int)(damp->reuse_limit * (pow(2,
(double)damp->max_suppress_time
/ damp->half_life)));
/* Decay-array computations */
damp->decay_array_size = ceil ((double) damp->max_suppress_time / DELTA_T);
damp->decay_array_size =
ceil((double)damp->max_suppress_time / DELTA_T);
damp->decay_array = XMALLOC(MTYPE_BGP_DAMP_ARRAY,
sizeof(double) * (damp->decay_array_size));
damp->decay_array[0] = 1.0;
damp->decay_array[1] = exp ((1.0/((double)damp->half_life/DELTA_T)) * log(0.5));
damp->decay_array[1] =
exp((1.0 / ((double)damp->half_life / DELTA_T)) * log(0.5));
/* Calculate decay values for all possible times */
for (i = 2; i < damp->decay_array_size; i++)
damp->decay_array[i] = damp->decay_array[i-1] * damp->decay_array[1];
damp->decay_array[i] =
damp->decay_array[i - 1] * damp->decay_array[1];
/* Reuse-list computations */
i = ceil((double)damp->max_suppress_time / DELTA_REUSE) + 1;
@ -415,28 +403,29 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
sizeof(int) * damp->reuse_index_size);
reuse_max_ratio = (double)damp->ceiling / damp->reuse_limit;
j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0));
j = (exp((double)damp->max_suppress_time / damp->half_life)
* log10(2.0));
if (reuse_max_ratio > j && j != 0)
reuse_max_ratio = j;
damp->scale_factor = (double)damp->reuse_index_size/(reuse_max_ratio - 1);
damp->scale_factor =
(double)damp->reuse_index_size / (reuse_max_ratio - 1);
for (i = 0; i < damp->reuse_index_size; i++)
{
for (i = 0; i < damp->reuse_index_size; i++) {
damp->reuse_index[i] =
(int)(((double)damp->half_life / DELTA_REUSE)
* log10 (1.0 / (damp->reuse_limit * ( 1.0 + ((double)i/damp->scale_factor)))) / log10(0.5));
* log10(1.0 / (damp->reuse_limit
* (1.0 + ((double)i
/ damp->scale_factor))))
/ log10(0.5));
}
}
int
bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
unsigned int reuse, unsigned int suppress, time_t max)
{
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
{
if (damp->half_life == half
&& damp->reuse_limit == reuse
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
if (damp->half_life == half && damp->reuse_limit == reuse
&& damp->suppress_value == suppress
&& damp->max_suppress_time == max)
return 0;
@ -453,8 +442,7 @@ bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
return 0;
}
static void
bgp_damp_config_clean (struct bgp_damp_config *damp)
static void bgp_damp_config_clean(struct bgp_damp_config *damp)
{
/* Free decay array */
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
@ -467,37 +455,32 @@ bgp_damp_config_clean (struct bgp_damp_config *damp)
}
/* Clean all the bgp_damp_info stored in reuse_list. */
void
bgp_damp_info_clean (void)
void bgp_damp_info_clean(void)
{
unsigned int i;
struct bgp_damp_info *bdi, *next;
damp->reuse_offset = 0;
for (i = 0; i < damp->reuse_list_size; i++)
{
for (i = 0; i < damp->reuse_list_size; i++) {
if (!damp->reuse_list[i])
continue;
for (bdi = damp->reuse_list[i]; bdi; bdi = next)
{
for (bdi = damp->reuse_list[i]; bdi; bdi = next) {
next = bdi->next;
bgp_damp_info_free(bdi, 1);
}
damp->reuse_list[i] = NULL;
}
for (bdi = damp->no_reuse_list; bdi; bdi = next)
{
for (bdi = damp->no_reuse_list; bdi; bdi = next) {
next = bdi->next;
bgp_damp_info_free(bdi, 1);
}
damp->no_reuse_list = NULL;
}
int
bgp_damp_disable (struct bgp *bgp, afi_t afi, safi_t safi)
int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi)
{
/* If it wasn't enabled, there's nothing to do. */
if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
@ -518,96 +501,96 @@ bgp_damp_disable (struct bgp *bgp, afi_t afi, safi_t safi)
return 0;
}
void
bgp_config_write_damp (struct vty *vty)
void bgp_config_write_damp(struct vty *vty)
{
if (bgp_damp_cfg.half_life == DEFAULT_HALF_LIFE * 60
&& bgp_damp_cfg.reuse_limit == DEFAULT_REUSE
&& bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS
&& bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life * 4)
vty_outln (vty, " bgp dampening");
vty_out(vty, " bgp dampening\n");
else if (bgp_damp_cfg.half_life != DEFAULT_HALF_LIFE * 60
&& bgp_damp_cfg.reuse_limit == DEFAULT_REUSE
&& bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS
&& bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life*4)
vty_outln (vty, " bgp dampening %lld",
&& bgp_damp_cfg.max_suppress_time
== bgp_damp_cfg.half_life * 4)
vty_out(vty, " bgp dampening %lld\n",
bgp_damp_cfg.half_life / 60LL);
else
vty_outln (vty, " bgp dampening %lld %d %d %lld",
bgp_damp_cfg.half_life/60LL,
bgp_damp_cfg.reuse_limit,
vty_out(vty, " bgp dampening %lld %d %d %lld\n",
bgp_damp_cfg.half_life / 60LL, bgp_damp_cfg.reuse_limit,
bgp_damp_cfg.suppress_value,
bgp_damp_cfg.max_suppress_time / 60LL);
}
static const char *
bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len, u_char use_json, json_object *json)
static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
size_t len, u_char use_json,
json_object *json)
{
time_t reuse_time = 0;
struct tm *tm = NULL;
int time_store = 0;
if (penalty > damp->reuse_limit)
{
reuse_time = (int) (DELTA_T * ((log((double)damp->reuse_limit/penalty))/(log(damp->decay_array[1]))));
if (penalty > damp->reuse_limit) {
reuse_time = (int)(DELTA_T
* ((log((double)damp->reuse_limit / penalty))
/ (log(damp->decay_array[1]))));
if (reuse_time > damp->max_suppress_time)
reuse_time = damp->max_suppress_time;
tm = gmtime(&reuse_time);
}
else
} else
reuse_time = 0;
/* Making formatted timer strings. */
#define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7
if (reuse_time == 0)
{
if (reuse_time == 0) {
if (use_json)
json_object_int_add(json, "reuseTimerMsecs", 0);
else
snprintf(buf, len, "00:00:00");
}
else if (reuse_time < ONE_DAY_SECOND)
{
if (use_json)
{
time_store = (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs", time_store);
}
else
snprintf (buf, len, "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
else if (reuse_time < ONE_WEEK_SECOND)
{
if (use_json)
{
time_store = (86400000 * tm->tm_yday) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs", time_store);
}
else
snprintf (buf, len, "%dd%02dh%02dm",
tm->tm_yday, tm->tm_hour, tm->tm_min);
}
else
{
if (use_json)
{
time_store = (604800000 * tm->tm_yday/7) + (86400000 * (tm->tm_yday - ((tm->tm_yday/7) * 7))) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs", time_store);
}
else
snprintf (buf, len, "%02dw%dd%02dh",
tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
} else if (reuse_time < ONE_DAY_SECOND) {
if (use_json) {
time_store = (3600000 * tm->tm_hour)
+ (60000 * tm->tm_min)
+ (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs",
time_store);
} else
snprintf(buf, len, "%02d:%02d:%02d", tm->tm_hour,
tm->tm_min, tm->tm_sec);
} else if (reuse_time < ONE_WEEK_SECOND) {
if (use_json) {
time_store = (86400000 * tm->tm_yday)
+ (3600000 * tm->tm_hour)
+ (60000 * tm->tm_min)
+ (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs",
time_store);
} else
snprintf(buf, len, "%dd%02dh%02dm", tm->tm_yday,
tm->tm_hour, tm->tm_min);
} else {
if (use_json) {
time_store =
(604800000 * tm->tm_yday / 7)
+ (86400000
* (tm->tm_yday - ((tm->tm_yday / 7) * 7)))
+ (3600000 * tm->tm_hour) + (60000 * tm->tm_min)
+ (1000 * tm->tm_sec);
json_object_int_add(json, "reuseTimerMsecs",
time_store);
} else
snprintf(buf, len, "%02dw%dd%02dh", tm->tm_yday / 7,
tm->tm_yday - ((tm->tm_yday / 7) * 7),
tm->tm_hour);
}
return buf;
}
void
bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo,
void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
json_object *json_path)
{
struct bgp_damp_info *bdi;
@ -631,34 +614,37 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo,
t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay(t_diff, bdi->penalty);
if (json_path)
{
if (json_path) {
json_object_int_add(json_path, "dampeningPenalty", penalty);
json_object_int_add(json_path, "dampeningFlapCount", bdi->flap);
peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 1, json_path);
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 1,
json_path);
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 1, json_path);
}
else
{
vty_out (vty, " Dampinfo: penalty %d, flapped %d times in %s",
bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, 1,
json_path);
} else {
vty_out(vty,
" Dampinfo: penalty %d, flapped %d times in %s",
penalty, bdi->flap,
peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, json_path));
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0,
json_path));
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
vty_out(vty, ", reuse in %s",
bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 0, json_path));
bgp_get_reuse_time(penalty, timebuf,
BGP_UPTIME_LEN, 0,
json_path));
vty_out (vty, VTYNL);
vty_out(vty, "\n");
}
}
const char *
bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo,
char *timebuf, size_t len, u_char use_json, json_object *json)
const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo,
char *timebuf, size_t len, u_char use_json,
json_object *json)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
@ -683,34 +669,27 @@ bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo,
return bgp_get_reuse_time(penalty, timebuf, len, use_json, json);
}
int
bgp_show_dampening_parameters (struct vty *vty, afi_t afi, safi_t safi)
int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi)
{
struct bgp *bgp;
bgp = bgp_get_default();
if (bgp == NULL)
{
vty_outln (vty, "No BGP process is configured");
if (bgp == NULL) {
vty_out(vty, "No BGP process is configured\n");
return CMD_WARNING;
}
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
{
vty_outln (vty, "Half-life time: %lld min",
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) {
vty_out(vty, "Half-life time: %lld min\n",
(long long)damp->half_life / 60);
vty_outln (vty, "Reuse penalty: %d",
damp->reuse_limit);
vty_outln (vty, "Suppress penalty: %d",
damp->suppress_value);
vty_outln (vty, "Max suppress time: %lld min",
vty_out(vty, "Reuse penalty: %d\n", damp->reuse_limit);
vty_out(vty, "Suppress penalty: %d\n", damp->suppress_value);
vty_out(vty, "Max suppress time: %lld min\n",
(long long)damp->max_suppress_time / 60);
vty_outln (vty, "Max supress penalty: %u",
damp->ceiling);
vty_out (vty, VTYNL);
}
else
vty_outln (vty, "dampening not enabled for %s",
vty_out(vty, "Max supress penalty: %u\n", damp->ceiling);
vty_out(vty, "\n");
} else
vty_out(vty, "dampening not enabled for %s\n",
afi == AFI_IP ? "IPv4" : "IPv6");
return CMD_SUCCESS;

View File

@ -22,8 +22,7 @@
#define _QUAGGA_BGP_DAMP_H
/* Structure maintained on a per-route basis. */
struct bgp_damp_info
{
struct bgp_damp_info {
/* Doubly linked list. This information must be linked to
reuse_list or no_reuse_list. */
struct bgp_damp_info *next;
@ -63,8 +62,7 @@ struct bgp_damp_info
};
/* Specified parameter set configuration. */
struct bgp_damp_config
{
struct bgp_damp_config {
/* Value over which routes suppressed. */
unsigned int suppress_value;
@ -132,17 +130,19 @@ struct bgp_damp_config
extern int bgp_damp_enable(struct bgp *, afi_t, safi_t, time_t, unsigned int,
unsigned int, time_t);
extern int bgp_damp_disable(struct bgp *, afi_t, safi_t);
extern int bgp_damp_withdraw (struct bgp_info *, struct bgp_node *,
afi_t, safi_t, int);
extern int bgp_damp_withdraw(struct bgp_info *, struct bgp_node *, afi_t,
safi_t, int);
extern int bgp_damp_update(struct bgp_info *, struct bgp_node *, afi_t, safi_t);
extern int bgp_damp_scan(struct bgp_info *, afi_t, safi_t);
extern void bgp_damp_info_free(struct bgp_damp_info *, int);
extern void bgp_damp_info_clean(void);
extern int bgp_damp_decay(time_t, int);
extern void bgp_config_write_damp(struct vty *);
extern void bgp_damp_info_vty (struct vty *, struct bgp_info *, json_object *json_path);
extern void bgp_damp_info_vty(struct vty *, struct bgp_info *,
json_object *json_path);
extern const char *bgp_damp_reuse_time_vty(struct vty *, struct bgp_info *,
char *, size_t, u_char, json_object *);
char *, size_t, u_char,
json_object *);
extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t);
#endif /* _QUAGGA_BGP_DAMP_H */

File diff suppressed because it is too large Load Diff

View File

@ -92,8 +92,7 @@ extern struct list *bgp_debug_update_prefixes;
extern struct list *bgp_debug_bestpath_prefixes;
extern struct list *bgp_debug_zebra_prefixes;
struct bgp_debug_filter
{
struct bgp_debug_filter {
char *host;
struct prefix *p;
};
@ -153,8 +152,10 @@ extern int bgp_debug_bestpath(struct prefix *p);
extern int bgp_debug_zebra(struct prefix *p);
extern int bgp_debug_count(void);
extern const char *bgp_debug_rdpfxpath2str (struct prefix_rd *, union prefixconstptr,
extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *,
union prefixconstptr, mpls_label_t *,
int, u_int32_t, char *, int);
const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data, size_t datalen);
const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data,
size_t datalen);
#endif /* _QUAGGA_BGP_DEBUG_H */

View File

@ -37,8 +37,7 @@
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_dump.h"
enum bgp_dump_type
{
enum bgp_dump_type {
BGP_DUMP_ALL,
BGP_DUMP_ALL_ET,
BGP_DUMP_UPDATES,
@ -49,14 +48,10 @@ enum bgp_dump_type
static const struct bgp_dump_type_map {
enum bgp_dump_type type;
const char *str;
} bgp_dump_type_map[] =
{
{BGP_DUMP_ALL, "all"},
{BGP_DUMP_ALL_ET, "all-et"},
{BGP_DUMP_UPDATES, "updates"},
{BGP_DUMP_UPDATES_ET, "updates-et"},
{BGP_DUMP_ROUTES, "routes-mrt"},
{0, NULL},
} bgp_dump_type_map[] = {
{BGP_DUMP_ALL, "all"}, {BGP_DUMP_ALL_ET, "all-et"},
{BGP_DUMP_UPDATES, "updates"}, {BGP_DUMP_UPDATES_ET, "updates-et"},
{BGP_DUMP_ROUTES, "routes-mrt"}, {0, NULL},
};
enum MRT_MSG_TYPES {
@ -76,8 +71,7 @@ enum MRT_MSG_TYPES {
MSG_TABLE_DUMP_V2 /* routing table dump, version 2 */
};
struct bgp_dump
{
struct bgp_dump {
enum bgp_dump_type type;
char *filename;
@ -106,8 +100,7 @@ struct bgp_dump bgp_dump_updates;
/* BGP dump structure for 'dump bgp routes' */
struct bgp_dump bgp_dump_routes;
static FILE *
bgp_dump_open_file (struct bgp_dump *bgp_dump)
static FILE *bgp_dump_open_file(struct bgp_dump *bgp_dump)
{
int ret;
time_t clock;
@ -119,16 +112,13 @@ bgp_dump_open_file (struct bgp_dump *bgp_dump)
time(&clock);
tm = localtime(&clock);
if (bgp_dump->filename[0] != DIRECTORY_SEP)
{
if (bgp_dump->filename[0] != DIRECTORY_SEP) {
sprintf(fullpath, "%s/%s", vty_get_cwd(), bgp_dump->filename);
ret = strftime(realpath, MAXPATHLEN, fullpath, tm);
}
else
} else
ret = strftime(realpath, MAXPATHLEN, bgp_dump->filename, tm);
if (ret == 0)
{
if (ret == 0) {
zlog_warn("bgp_dump_open_file: strftime error");
return NULL;
}
@ -140,9 +130,9 @@ bgp_dump_open_file (struct bgp_dump *bgp_dump)
oldumask = umask(0777 & ~LOGFILE_MASK);
bgp_dump->fp = fopen(realpath, "w");
if (bgp_dump->fp == NULL)
{
zlog_warn ("bgp_dump_open_file: %s: %s", realpath, strerror (errno));
if (bgp_dump->fp == NULL) {
zlog_warn("bgp_dump_open_file: %s: %s", realpath,
strerror(errno));
umask(oldumask);
return NULL;
}
@ -151,44 +141,44 @@ bgp_dump_open_file (struct bgp_dump *bgp_dump)
return bgp_dump->fp;
}
static int
bgp_dump_interval_add (struct bgp_dump *bgp_dump, int interval)
static int bgp_dump_interval_add(struct bgp_dump *bgp_dump, int interval)
{
int secs_into_day;
time_t t;
struct tm *tm;
if (interval > 0)
{
if (interval > 0) {
/* Periodic dump every interval seconds */
if ((interval < 86400) && ((86400 % interval) == 0))
{
/* Dump at predictable times: if a day has a whole number of
* intervals, dump every interval seconds starting from midnight
if ((interval < 86400) && ((86400 % interval) == 0)) {
/* Dump at predictable times: if a day has a whole
* number of
* intervals, dump every interval seconds starting from
* midnight
*/
(void)time(&t);
tm = localtime(&t);
secs_into_day = tm->tm_sec + 60*tm->tm_min + 60*60*tm->tm_hour;
interval = interval - secs_into_day % interval; /* always > 0 */
secs_into_day = tm->tm_sec + 60 * tm->tm_min
+ 60 * 60 * tm->tm_hour;
interval = interval
- secs_into_day % interval; /* always > 0 */
}
bgp_dump->t_interval = NULL;
thread_add_timer(bm->master, bgp_dump_interval_func, bgp_dump, interval,
&bgp_dump->t_interval);
}
else
{
/* One-off dump: execute immediately, don't affect any scheduled dumps */
thread_add_timer(bm->master, bgp_dump_interval_func, bgp_dump,
interval, &bgp_dump->t_interval);
} else {
/* One-off dump: execute immediately, don't affect any scheduled
* dumps */
bgp_dump->t_interval = NULL;
thread_add_event(bm->master, bgp_dump_interval_func, bgp_dump, 0,
&bgp_dump->t_interval);
thread_add_event(bm->master, bgp_dump_interval_func, bgp_dump,
0, &bgp_dump->t_interval);
}
return 0;
}
/* Dump common header. */
static void
bgp_dump_header (struct stream *obuf, int type, int subtype, int dump_type)
static void bgp_dump_header(struct stream *obuf, int type, int subtype,
int dump_type)
{
struct timeval clock;
long msecs;
@ -214,8 +204,7 @@ bgp_dump_header (struct stream *obuf, int type, int subtype, int dump_type)
stream_putl(obuf, msecs);
}
static void
bgp_dump_set_size (struct stream *s, int type)
static void bgp_dump_set_size(struct stream *s, int type)
{
/*
* The BGP_DUMP_HEADER_SIZE stay at 12 event when ET:
@ -225,8 +214,7 @@ bgp_dump_set_size (struct stream *s, int type)
stream_putl_at(s, 8, stream_get_endp(s) - BGP_DUMP_HEADER_SIZE);
}
static void
bgp_dump_routes_index_table(struct bgp *bgp)
static void bgp_dump_routes_index_table(struct bgp *bgp)
{
struct peer *peer;
struct listnode *node;
@ -244,13 +232,10 @@ bgp_dump_routes_index_table(struct bgp *bgp)
stream_put_in_addr(obuf, &bgp->router_id);
/* View name */
if(bgp->name)
{
if (bgp->name) {
stream_putw(obuf, strlen(bgp->name));
stream_put(obuf, bgp->name, strlen(bgp->name));
}
else
{
} else {
stream_putw(obuf, 0);
}
@ -259,7 +244,9 @@ bgp_dump_routes_index_table(struct bgp *bgp)
/* Populate fake peer at index 0, for locally originated routes */
/* Peer type (IPv4) */
stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
stream_putc(obuf,
TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4
+ TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
/* Peer BGP ID (0.0.0.0) */
stream_putl(obuf, 0);
/* Peer IP address (0.0.0.0) */
@ -268,35 +255,35 @@ bgp_dump_routes_index_table(struct bgp *bgp)
stream_putl(obuf, 0);
/* Walk down all peers */
for(ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
{
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
/* Peer's type */
if (sockunion_family(&peer->su) == AF_INET)
{
stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
}
else if (sockunion_family(&peer->su) == AF_INET6)
{
stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6);
if (sockunion_family(&peer->su) == AF_INET) {
stream_putc(
obuf,
TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4
+ TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
} else if (sockunion_family(&peer->su) == AF_INET6) {
stream_putc(
obuf,
TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4
+ TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6);
}
/* Peer's BGP ID */
stream_put_in_addr(obuf, &peer->remote_id);
/* Peer's IP address */
if (sockunion_family(&peer->su) == AF_INET)
{
if (sockunion_family(&peer->su) == AF_INET) {
stream_put_in_addr(obuf, &peer->su.sin.sin_addr);
}
else if (sockunion_family(&peer->su) == AF_INET6)
{
} else if (sockunion_family(&peer->su) == AF_INET6) {
stream_write(obuf, (u_char *)&peer->su.sin6.sin6_addr,
IPV6_MAX_BYTELEN);
}
/* Peer's AS number. */
/* Note that, as this is an AS4 compliant quagga, the RIB is always AS4 */
/* Note that, as this is an AS4 compliant quagga, the RIB is
* always AS4 */
stream_putl(obuf, peer->as);
/* Store the peer number for this peer */
@ -311,9 +298,9 @@ bgp_dump_routes_index_table(struct bgp *bgp)
}
static struct bgp_info *
bgp_dump_route_node_record (int afi, struct bgp_node *rn,
struct bgp_info *info, unsigned int seq)
static struct bgp_info *bgp_dump_route_node_record(int afi, struct bgp_node *rn,
struct bgp_info *info,
unsigned int seq)
{
struct stream *obuf;
size_t sizep;
@ -324,10 +311,12 @@ bgp_dump_route_node_record (int afi, struct bgp_node *rn,
/* MRT header */
if (afi == AFI_IP)
bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST,
bgp_dump_header(obuf, MSG_TABLE_DUMP_V2,
TABLE_DUMP_V2_RIB_IPV4_UNICAST,
BGP_DUMP_ROUTES);
else if (afi == AFI_IP6)
bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST,
bgp_dump_header(obuf, MSG_TABLE_DUMP_V2,
TABLE_DUMP_V2_RIB_IPV6_UNICAST,
BGP_DUMP_ROUTES);
/* Sequence number */
@ -337,15 +326,16 @@ bgp_dump_route_node_record (int afi, struct bgp_node *rn,
stream_putc(obuf, rn->p.prefixlen);
/* Prefix */
if (afi == AFI_IP)
{
/* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
stream_write (obuf, (u_char *)&rn->p.u.prefix4, (rn->p.prefixlen+7)/8);
}
else if (afi == AFI_IP6)
{
/* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
stream_write (obuf, (u_char *)&rn->p.u.prefix6, (rn->p.prefixlen+7)/8);
if (afi == AFI_IP) {
/* We'll dump only the useful bits (those not 0), but have to
* align on 8 bits */
stream_write(obuf, (u_char *)&rn->p.u.prefix4,
(rn->p.prefixlen + 7) / 8);
} else if (afi == AFI_IP6) {
/* We'll dump only the useful bits (those not 0), but have to
* align on 8 bits */
stream_write(obuf, (u_char *)&rn->p.u.prefix6,
(rn->p.prefixlen + 7) / 8);
}
/* Save where we are now, so we can overwride the entry count later */
@ -358,8 +348,7 @@ bgp_dump_route_node_record (int afi, struct bgp_node *rn,
stream_putw(obuf, 0);
endp = stream_get_endp(obuf);
for (; info; info = info->next)
{
for (; info; info = info->next) {
size_t cur_endp;
/* Peer index */
@ -374,8 +363,7 @@ bgp_dump_route_node_record (int afi, struct bgp_node *rn,
cur_endp = stream_get_endp(obuf);
if (cur_endp > BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
+ BGP_DUMP_HEADER_SIZE)
{
+ BGP_DUMP_HEADER_SIZE) {
stream_set_endp(obuf, endp);
break;
}
@ -395,8 +383,8 @@ bgp_dump_route_node_record (int afi, struct bgp_node *rn,
/* Runs under child process. */
static unsigned int
bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
static unsigned int bgp_dump_routes_func(int afi, int first_run,
unsigned int seq)
{
struct bgp_info *info;
struct bgp_node *rn;
@ -411,7 +399,8 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
return seq;
/* Note that bgp_dump_routes_index_table will do ipv4 and ipv6 peers,
so this should only be done on the first call to bgp_dump_routes_func.
so this should only be done on the first call to
bgp_dump_routes_func.
( this function will be called once for ipv4 and once for ipv6 ) */
if (first_run)
bgp_dump_routes_index_table(bgp);
@ -419,11 +408,9 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
/* Walk down each BGP route. */
table = bgp->rib[afi][SAFI_UNICAST];
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
{
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
info = rn->info;
while (info)
{
while (info) {
info = bgp_dump_route_node_record(afi, rn, info, seq);
seq++;
}
@ -434,24 +421,24 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
return seq;
}
static int
bgp_dump_interval_func (struct thread *t)
static int bgp_dump_interval_func(struct thread *t)
{
struct bgp_dump *bgp_dump;
bgp_dump = THREAD_ARG(t);
bgp_dump->t_interval = NULL;
/* Reschedule dump even if file couldn't be opened this time... */
if (bgp_dump_open_file (bgp_dump) != NULL)
{
/* In case of bgp_dump_routes, we need special route dump function. */
if (bgp_dump->type == BGP_DUMP_ROUTES)
{
if (bgp_dump_open_file(bgp_dump) != NULL) {
/* In case of bgp_dump_routes, we need special route dump
* function. */
if (bgp_dump->type == BGP_DUMP_ROUTES) {
unsigned int seq = bgp_dump_routes_func(AFI_IP, 1, 0);
bgp_dump_routes_func(AFI_IP6, 0, seq);
/* Close the file now. For a RIB dump there's no point in leaving
/* Close the file now. For a RIB dump there's no point
* in leaving
* it open until the next scheduled dump starts. */
fclose(bgp_dump->fp); bgp_dump->fp = NULL;
fclose(bgp_dump->fp);
bgp_dump->fp = NULL;
}
}
@ -463,37 +450,32 @@ bgp_dump_interval_func (struct thread *t)
}
/* Dump common information. */
static void
bgp_dump_common (struct stream *obuf, struct peer *peer, int forceas4)
static void bgp_dump_common(struct stream *obuf, struct peer *peer,
int forceas4)
{
char empty[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/* Source AS number and Destination AS number. */
if (forceas4 || CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
{
if (forceas4 || CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) {
stream_putl(obuf, peer->as);
stream_putl(obuf, peer->local_as);
}
else
{
} else {
stream_putw(obuf, peer->as);
stream_putw(obuf, peer->local_as);
}
if (peer->su.sa.sa_family == AF_INET)
{
if (peer->su.sa.sa_family == AF_INET) {
stream_putw(obuf, peer->ifindex);
stream_putw(obuf, AFI_IP);
stream_put(obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN);
if (peer->su_local)
stream_put (obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN);
stream_put(obuf, &peer->su_local->sin.sin_addr,
IPV4_MAX_BYTELEN);
else
stream_put(obuf, empty, IPV4_MAX_BYTELEN);
}
else if (peer->su.sa.sa_family == AF_INET6)
{
} else if (peer->su.sa.sa_family == AF_INET6) {
/* Interface Index and Address family. */
stream_putw(obuf, peer->ifindex);
stream_putw(obuf, AFI_IP6);
@ -502,15 +484,15 @@ bgp_dump_common (struct stream *obuf, struct peer *peer, int forceas4)
stream_put(obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN);
if (peer->su_local)
stream_put (obuf, &peer->su_local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
stream_put(obuf, &peer->su_local->sin6.sin6_addr,
IPV6_MAX_BYTELEN);
else
stream_put(obuf, empty, IPV6_MAX_BYTELEN);
}
}
/* Dump BGP status change. */
void
bgp_dump_state (struct peer *peer, int status_old, int status_new)
void bgp_dump_state(struct peer *peer, int status_old, int status_new)
{
struct stream *obuf;
@ -537,8 +519,7 @@ bgp_dump_state (struct peer *peer, int status_old, int status_new)
fflush(bgp_dump_all.fp);
}
static void
bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
static void bgp_dump_packet_func(struct bgp_dump *bgp_dump, struct peer *peer,
struct stream *packet)
{
struct stream *obuf;
@ -552,13 +533,10 @@ bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
stream_reset(obuf);
/* Dump header and common part. */
if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
{
if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) {
bgp_dump_header(obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE_AS4,
bgp_dump->type);
}
else
{
} else {
bgp_dump_header(obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE,
bgp_dump->type);
}
@ -576,8 +554,7 @@ bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
}
/* Called from bgp_packet.c when BGP packet is received. */
void
bgp_dump_packet (struct peer *peer, int type, struct stream *packet)
void bgp_dump_packet(struct peer *peer, int type, struct stream *packet)
{
/* bgp_dump_all. */
bgp_dump_packet_func(&bgp_dump_all, peer, packet);
@ -587,8 +564,7 @@ bgp_dump_packet (struct peer *peer, int type, struct stream *packet)
bgp_dump_packet_func(&bgp_dump_updates, peer, packet);
}
static unsigned int
bgp_dump_parse_time (const char *str)
static unsigned int bgp_dump_parse_time(const char *str)
{
int i;
int len;
@ -603,15 +579,11 @@ bgp_dump_parse_time (const char *str)
seen_m = 0;
len = strlen(str);
for (i = 0; i < len; i++)
{
if (isdigit ((int) str[i]))
{
for (i = 0; i < len; i++) {
if (isdigit((int)str[i])) {
time *= 10;
time += str[i] - '0';
}
else if (str[i] == 'H' || str[i] == 'h')
{
} else if (str[i] == 'H' || str[i] == 'h') {
if (seen_h)
return 0;
if (seen_m)
@ -619,23 +591,19 @@ bgp_dump_parse_time (const char *str)
total += time * 60 * 60;
time = 0;
seen_h = 1;
}
else if (str[i] == 'M' || str[i] == 'm')
{
} else if (str[i] == 'M' || str[i] == 'm') {
if (seen_m)
return 0;
total += time * 60;
time = 0;
seen_m = 1;
}
else
} else
return 0;
}
return total + time;
}
static int
bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
static int bgp_dump_set(struct vty *vty, struct bgp_dump *bgp_dump,
enum bgp_dump_type type, const char *path,
const char *interval_str)
{
@ -643,16 +611,13 @@ bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
/* Don't schedule duplicate dumps if the dump command is given twice */
if (bgp_dump->filename && strcmp(path, bgp_dump->filename) == 0
&& type == bgp_dump->type)
{
if (interval_str)
{
if (bgp_dump->interval_str &&
strcmp(bgp_dump->interval_str, interval_str) == 0)
&& type == bgp_dump->type) {
if (interval_str) {
if (bgp_dump->interval_str
&& strcmp(bgp_dump->interval_str, interval_str)
== 0)
return CMD_SUCCESS;
}
else
{
} else {
if (!bgp_dump->interval_str)
return CMD_SUCCESS;
}
@ -661,21 +626,18 @@ bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
/* Removing previous config */
bgp_dump_unset(bgp_dump);
if (interval_str)
{
if (interval_str) {
/* Check interval string. */
interval = bgp_dump_parse_time(interval_str);
if (interval == 0)
{
vty_outln (vty, "Malformed interval string");
return CMD_WARNING;
if (interval == 0) {
vty_out(vty, "Malformed interval string\n");
return CMD_WARNING_CONFIG_FAILED;
}
/* Setting interval string */
bgp_dump->interval_str = XSTRDUP(MTYPE_BGP_DUMP_STR, interval_str);
}
else
{
bgp_dump->interval_str =
XSTRDUP(MTYPE_BGP_DUMP_STR, interval_str);
} else {
interval = 0;
}
@ -697,26 +659,22 @@ bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump,
return CMD_SUCCESS;
}
static int
bgp_dump_unset (struct bgp_dump *bgp_dump)
static int bgp_dump_unset(struct bgp_dump *bgp_dump)
{
/* Removing file name. */
if (bgp_dump->filename)
{
if (bgp_dump->filename) {
XFREE(MTYPE_BGP_DUMP_STR, bgp_dump->filename);
bgp_dump->filename = NULL;
}
/* Closing file. */
if (bgp_dump->fp)
{
if (bgp_dump->fp) {
fclose(bgp_dump->fp);
bgp_dump->fp = NULL;
}
/* Removing interval thread. */
if (bgp_dump->t_interval)
{
if (bgp_dump->t_interval) {
thread_cancel(bgp_dump->t_interval);
bgp_dump->t_interval = NULL;
}
@ -724,8 +682,7 @@ bgp_dump_unset (struct bgp_dump *bgp_dump)
bgp_dump->interval = 0;
/* Removing interval string. */
if (bgp_dump->interval_str)
{
if (bgp_dump->interval_str) {
XFREE(MTYPE_BGP_DUMP_STR, bgp_dump->interval_str);
bgp_dump->interval_str = NULL;
}
@ -756,8 +713,7 @@ DEFUN (dump_bgp_all,
if (strmatch(argv[idx_dump_routes]->text, map->str))
bgp_dump_type = map->type;
switch (bgp_dump_type)
{
switch (bgp_dump_type) {
case BGP_DUMP_ALL:
case BGP_DUMP_ALL_ET:
bgp_dump_struct = &bgp_dump_all;
@ -803,8 +759,7 @@ DEFUN (no_dump_bgp_all,
if (strmatch(argv[idx_dump_routes]->text, map->str))
bgp_dump_type = map->type;
switch (bgp_dump_type)
{
switch (bgp_dump_type) {
case BGP_DUMP_ALL:
case BGP_DUMP_ALL_ET:
bgp_dump_struct = &bgp_dump_all;
@ -823,12 +778,7 @@ DEFUN (no_dump_bgp_all,
}
/* BGP node structure. */
static struct cmd_node bgp_dump_node =
{
DUMP_NODE,
"",
1
};
static struct cmd_node bgp_dump_node = {DUMP_NODE, "", 1};
#if 0
char *
@ -856,58 +806,56 @@ config_time2str (unsigned int interval)
}
#endif
static int
config_write_bgp_dump (struct vty *vty)
{
if (bgp_dump_all.filename)
static int config_write_bgp_dump(struct vty *vty)
{
if (bgp_dump_all.filename) {
const char *type_str = "all";
if (bgp_dump_all.type == BGP_DUMP_ALL_ET)
type_str = "all-et";
if (bgp_dump_all.interval_str)
vty_outln (vty, "dump bgp %s %s %s", type_str,
bgp_dump_all.filename,bgp_dump_all.interval_str);
vty_out(vty, "dump bgp %s %s %s\n", type_str,
bgp_dump_all.filename,
bgp_dump_all.interval_str);
else
vty_outln (vty, "dump bgp %s %s", type_str,
vty_out(vty, "dump bgp %s %s\n", type_str,
bgp_dump_all.filename);
}
if (bgp_dump_updates.filename)
{
if (bgp_dump_updates.filename) {
const char *type_str = "updates";
if (bgp_dump_updates.type == BGP_DUMP_UPDATES_ET)
type_str = "updates-et";
if (bgp_dump_updates.interval_str)
vty_outln (vty, "dump bgp %s %s %s", type_str,
bgp_dump_updates.filename,bgp_dump_updates.interval_str);
vty_out(vty, "dump bgp %s %s %s\n", type_str,
bgp_dump_updates.filename,
bgp_dump_updates.interval_str);
else
vty_outln (vty, "dump bgp %s %s", type_str,
vty_out(vty, "dump bgp %s %s\n", type_str,
bgp_dump_updates.filename);
}
if (bgp_dump_routes.filename)
{
if (bgp_dump_routes.filename) {
if (bgp_dump_routes.interval_str)
vty_outln (vty, "dump bgp routes-mrt %s %s",
bgp_dump_routes.filename,bgp_dump_routes.interval_str);
vty_out(vty, "dump bgp routes-mrt %s %s\n",
bgp_dump_routes.filename,
bgp_dump_routes.interval_str);
else
vty_outln (vty, "dump bgp routes-mrt %s",
vty_out(vty, "dump bgp routes-mrt %s\n",
bgp_dump_routes.filename);
}
return 0;
}
/* Initialize BGP packet dump functionality. */
void
bgp_dump_init (void)
void bgp_dump_init(void)
{
memset(&bgp_dump_all, 0, sizeof(struct bgp_dump));
memset(&bgp_dump_updates, 0, sizeof(struct bgp_dump));
memset(&bgp_dump_routes, 0, sizeof(struct bgp_dump));
bgp_dump_obuf = stream_new ((BGP_MAX_PACKET_SIZE << 1)
+ BGP_DUMP_MSG_HEADER + BGP_DUMP_HEADER_SIZE);
bgp_dump_obuf =
stream_new((BGP_MAX_PACKET_SIZE << 1) + BGP_DUMP_MSG_HEADER
+ BGP_DUMP_HEADER_SIZE);
install_node(&bgp_dump_node, config_write_bgp_dump);
@ -915,8 +863,7 @@ bgp_dump_init (void)
install_element(CONFIG_NODE, &no_dump_bgp_all_cmd);
}
void
bgp_dump_finish (void)
void bgp_dump_finish(void)
{
bgp_dump_unset(&bgp_dump_all);
bgp_dump_unset(&bgp_dump_updates);

View File

@ -36,16 +36,14 @@
static struct hash *ecomhash;
/* Allocate a new ecommunities. */
struct ecommunity *
ecommunity_new (void)
struct ecommunity *ecommunity_new(void)
{
return (struct ecommunity *)XCALLOC(MTYPE_ECOMMUNITY,
sizeof(struct ecommunity));
}
/* Allocate ecommunities. */
void
ecommunity_free (struct ecommunity **ecom)
void ecommunity_free(struct ecommunity **ecom)
{
if ((*ecom)->val)
XFREE(MTYPE_ECOMMUNITY_VAL, (*ecom)->val);
@ -55,8 +53,7 @@ ecommunity_free (struct ecommunity **ecom)
ecom = NULL;
}
static void
ecommunity_hash_free (struct ecommunity *ecom)
static void ecommunity_hash_free(struct ecommunity *ecom)
{
ecommunity_free(&ecom);
}
@ -67,16 +64,14 @@ ecommunity_hash_free (struct ecommunity *ecom)
structure, we don't add the value. Newly added value is sorted by
numerical order. When the value is added to the structure return 1
else return 0. */
int
ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
int ecommunity_add_val(struct ecommunity *ecom, struct ecommunity_val *eval)
{
u_int8_t *p;
int ret;
int c;
/* When this is fist value, just add it. */
if (ecom->val == NULL)
{
if (ecom->val == NULL) {
ecom->size++;
ecom->val = XMALLOC(MTYPE_ECOMMUNITY_VAL, ecom_length(ecom));
memcpy(ecom->val, eval->val, ECOMMUNITY_SIZE);
@ -85,8 +80,7 @@ ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
/* If the value already exists in the structure return 0. */
c = 0;
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
{
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++) {
ret = memcmp(p, eval->val, ECOMMUNITY_SIZE);
if (ret == 0)
return 0;
@ -96,7 +90,8 @@ ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
/* Add the value to the structure with numerical sorting. */
ecom->size++;
ecom->val = XREALLOC (MTYPE_ECOMMUNITY_VAL, ecom->val, ecom_length (ecom));
ecom->val =
XREALLOC(MTYPE_ECOMMUNITY_VAL, ecom->val, ecom_length(ecom));
memmove(ecom->val + (c + 1) * ECOMMUNITY_SIZE,
ecom->val + c * ECOMMUNITY_SIZE,
@ -109,8 +104,7 @@ ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
/* This function takes pointer to Extended Communites strucutre then
create a new Extended Communities structure by uniq and sort each
Extended Communities value. */
struct ecommunity *
ecommunity_uniq_sort (struct ecommunity *ecom)
struct ecommunity *ecommunity_uniq_sort(struct ecommunity *ecom)
{
int i;
struct ecommunity *new;
@ -121,17 +115,16 @@ ecommunity_uniq_sort (struct ecommunity *ecom)
new = ecommunity_new();
for (i = 0; i < ecom->size; i++)
{
eval = (struct ecommunity_val *) (ecom->val + (i * ECOMMUNITY_SIZE));
for (i = 0; i < ecom->size; i++) {
eval = (struct ecommunity_val *)(ecom->val
+ (i * ECOMMUNITY_SIZE));
ecommunity_add_val(new, eval);
}
return new;
}
/* Parse Extended Communites Attribute in BGP packet. */
struct ecommunity *
ecommunity_parse (u_int8_t *pnt, u_short length)
struct ecommunity *ecommunity_parse(u_int8_t *pnt, u_short length)
{
struct ecommunity tmp;
struct ecommunity *new;
@ -153,53 +146,52 @@ ecommunity_parse (u_int8_t *pnt, u_short length)
}
/* Duplicate the Extended Communities Attribute structure. */
struct ecommunity *
ecommunity_dup (struct ecommunity *ecom)
struct ecommunity *ecommunity_dup(struct ecommunity *ecom)
{
struct ecommunity *new;
new = XCALLOC(MTYPE_ECOMMUNITY, sizeof(struct ecommunity));
new->size = ecom->size;
if (new->size)
{
new->val = XMALLOC (MTYPE_ECOMMUNITY_VAL, ecom->size * ECOMMUNITY_SIZE);
if (new->size) {
new->val = XMALLOC(MTYPE_ECOMMUNITY_VAL,
ecom->size * ECOMMUNITY_SIZE);
memcpy(new->val, ecom->val, ecom->size * ECOMMUNITY_SIZE);
}
else
} else
new->val = NULL;
return new;
}
/* Retrun string representation of communities attribute. */
char *
ecommunity_str (struct ecommunity *ecom)
char *ecommunity_str(struct ecommunity *ecom)
{
if (!ecom->str)
ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
ecom->str =
ecommunity_ecom2str(ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
return ecom->str;
}
/* Merge two Extended Communities Attribute structure. */
struct ecommunity *
ecommunity_merge (struct ecommunity *ecom1, struct ecommunity *ecom2)
struct ecommunity *ecommunity_merge(struct ecommunity *ecom1,
struct ecommunity *ecom2)
{
if (ecom1->val)
ecom1->val = XREALLOC (MTYPE_ECOMMUNITY_VAL, ecom1->val,
ecom1->val =
XREALLOC(MTYPE_ECOMMUNITY_VAL, ecom1->val,
(ecom1->size + ecom2->size) * ECOMMUNITY_SIZE);
else
ecom1->val = XMALLOC (MTYPE_ECOMMUNITY_VAL,
ecom1->val =
XMALLOC(MTYPE_ECOMMUNITY_VAL,
(ecom1->size + ecom2->size) * ECOMMUNITY_SIZE);
memcpy (ecom1->val + (ecom1->size * ECOMMUNITY_SIZE),
ecom2->val, ecom2->size * ECOMMUNITY_SIZE);
memcpy(ecom1->val + (ecom1->size * ECOMMUNITY_SIZE), ecom2->val,
ecom2->size * ECOMMUNITY_SIZE);
ecom1->size += ecom2->size;
return ecom1;
}
/* Intern Extended Communities Attribute. */
struct ecommunity *
ecommunity_intern (struct ecommunity *ecom)
struct ecommunity *ecommunity_intern(struct ecommunity *ecom)
{
struct ecommunity *find;
@ -213,14 +205,14 @@ ecommunity_intern (struct ecommunity *ecom)
find->refcnt++;
if (!find->str)
find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY, 0);
find->str =
ecommunity_ecom2str(find, ECOMMUNITY_FORMAT_DISPLAY, 0);
return find;
}
/* Unintern Extended Communities Attribute. */
void
ecommunity_unintern (struct ecommunity **ecom)
void ecommunity_unintern(struct ecommunity **ecom)
{
struct ecommunity *ret;
@ -228,8 +220,7 @@ ecommunity_unintern (struct ecommunity **ecom)
(*ecom)->refcnt--;
/* Pull off from hash. */
if ((*ecom)->refcnt == 0)
{
if ((*ecom)->refcnt == 0) {
/* Extended community must be in the hash. */
ret = (struct ecommunity *)hash_release(ecomhash, *ecom);
assert(ret != NULL);
@ -239,8 +230,7 @@ ecommunity_unintern (struct ecommunity **ecom)
}
/* Utinity function to make hash key. */
unsigned int
ecommunity_hash_make (void *arg)
unsigned int ecommunity_hash_make(void *arg)
{
const struct ecommunity *ecom = arg;
int size = ecom->size * ECOMMUNITY_SIZE;
@ -248,8 +238,7 @@ ecommunity_hash_make (void *arg)
unsigned int key = 0;
int c;
for (c = 0; c < size; c += ECOMMUNITY_SIZE)
{
for (c = 0; c < size; c += ECOMMUNITY_SIZE) {
key += pnt[c];
key += pnt[c + 1];
key += pnt[c + 2];
@ -264,8 +253,7 @@ ecommunity_hash_make (void *arg)
}
/* Compare two Extended Communities Attribute structure. */
int
ecommunity_cmp (const void *arg1, const void *arg2)
int ecommunity_cmp(const void *arg1, const void *arg2)
{
const struct ecommunity *ecom1 = arg1;
const struct ecommunity *ecom2 = arg2;
@ -277,18 +265,17 @@ ecommunity_cmp (const void *arg1, const void *arg2)
return 0;
return (ecom1->size == ecom2->size
&& memcmp (ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE) == 0);
&& memcmp(ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE)
== 0);
}
/* Initialize Extended Comminities related hash. */
void
ecommunity_init (void)
void ecommunity_init(void)
{
ecomhash = hash_create(ecommunity_hash_make, ecommunity_cmp, NULL);
}
void
ecommunity_finish (void)
void ecommunity_finish(void)
{
hash_clean(ecomhash, (void (*)(void *))ecommunity_hash_free);
hash_free(ecomhash);
@ -296,17 +283,62 @@ ecommunity_finish (void)
}
/* Extended Communities token enum. */
enum ecommunity_token
{
enum ecommunity_token {
ecommunity_token_unknown = 0,
ecommunity_token_rt,
ecommunity_token_soo,
ecommunity_token_val,
};
/*
* Encode BGP extended community from passed values. Supports types
* defined in RFC 4360 and well-known sub-types.
*/
static int ecommunity_encode(u_char type, u_char sub_type, int trans, as_t as,
struct in_addr ip, u_int32_t val,
struct ecommunity_val *eval)
{
assert(eval);
if (type == ECOMMUNITY_ENCODE_AS) {
if (as > BGP_AS_MAX)
return -1;
} else if (type == ECOMMUNITY_ENCODE_IP
|| type == ECOMMUNITY_ENCODE_AS4) {
if (val > UINT16_MAX)
return -1;
}
/* Fill in the values. */
eval->val[0] = type;
if (!trans)
eval->val[0] |= ECOMMUNITY_FLAG_NON_TRANSITIVE;
eval->val[1] = sub_type;
if (type == ECOMMUNITY_ENCODE_AS) {
eval->val[2] = (as >> 8) & 0xff;
eval->val[3] = as & 0xff;
eval->val[4] = (val >> 24) & 0xff;
eval->val[5] = (val >> 16) & 0xff;
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
} else if (type == ECOMMUNITY_ENCODE_IP) {
memcpy(&eval->val[2], &ip, sizeof(struct in_addr));
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
} else {
eval->val[2] = (as >> 24) & 0xff;
eval->val[3] = (as >> 16) & 0xff;
eval->val[4] = (as >> 8) & 0xff;
eval->val[5] = as & 0xff;
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
return 0;
}
/* Get next Extended Communities token from the string. */
static const char *
ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
static const char *ecommunity_gettoken(const char *str,
struct ecommunity_val *eval,
enum ecommunity_token *token)
{
int ret;
@ -318,11 +350,11 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
struct in_addr ip;
as_t as = 0;
u_int32_t val = 0;
u_char ecomm_type;
char buf[INET_ADDRSTRLEN + 1];
/* Skip white space. */
while (isspace ((int) *p))
{
while (isspace((int)*p)) {
p++;
str++;
}
@ -332,47 +364,38 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
return NULL;
/* "rt" and "soo" keyword parse. */
if (! isdigit ((int) *p))
{
if (!isdigit((int)*p)) {
/* "rt" match check. */
if (tolower ((int) *p) == 'r')
{
if (tolower((int)*p) == 'r') {
p++;
if (tolower ((int) *p) == 't')
{
if (tolower((int)*p) == 't') {
p++;
*token = ecommunity_token_rt;
return p;
}
if (isspace ((int) *p) || *p == '\0')
{
if (isspace((int)*p) || *p == '\0') {
*token = ecommunity_token_rt;
return p;
}
goto error;
}
/* "soo" match check. */
else if (tolower ((int) *p) == 's')
{
else if (tolower((int)*p) == 's') {
p++;
if (tolower ((int) *p) == 'o')
{
if (tolower((int)*p) == 'o') {
p++;
if (tolower ((int) *p) == 'o')
{
if (tolower((int)*p) == 'o') {
p++;
*token = ecommunity_token_soo;
return p;
}
if (isspace ((int) *p) || *p == '\0')
{
if (isspace((int)*p) || *p == '\0') {
*token = ecommunity_token_soo;
return p;
}
goto error;
}
if (isspace ((int) *p) || *p == '\0')
{
if (isspace((int)*p) || *p == '\0') {
*token = ecommunity_token_soo;
return p;
}
@ -394,10 +417,8 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
* OPQR: Four byte value
*
*/
while (isdigit ((int) *p) || *p == ':' || *p == '.')
{
if (*p == ':')
{
while (isdigit((int)*p) || *p == ':' || *p == '.') {
if (*p == ':') {
if (separator)
goto error;
@ -409,38 +430,30 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
memset(buf, 0, INET_ADDRSTRLEN + 1);
memcpy(buf, str, p - str);
if (dot)
{
if (dot) {
/* Parsing A.B.C.D in:
* A.B.C.D:MN
*/
ret = inet_aton(buf, &ip);
if (ret == 0)
goto error;
}
else
{
} else {
/* ASN */
as = strtoul(buf, &endptr, 10);
if (*endptr != '\0' || as == BGP_AS4_MAX)
goto error;
}
}
else if (*p == '.')
{
} else if (*p == '.') {
if (separator)
goto error;
dot++;
if (dot > 4)
goto error;
}
else
{
} else {
digit = 1;
/* We're past the IP/ASN part */
if (separator)
{
if (separator) {
val *= 10;
val += (*p - '0');
}
@ -452,44 +465,15 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
if (!digit || !separator)
goto error;
/* Encode result into routing distinguisher. */
/* Encode result into extended community. */
if (dot)
{
if (val > UINT16_MAX)
goto error;
eval->val[0] = ECOMMUNITY_ENCODE_IP;
eval->val[1] = 0;
memcpy (&eval->val[2], &ip, sizeof (struct in_addr));
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
ecomm_type = ECOMMUNITY_ENCODE_IP;
else if (as > BGP_AS_MAX)
{
if (val > UINT16_MAX)
goto error;
eval->val[0] = ECOMMUNITY_ENCODE_AS4;
eval->val[1] = 0;
eval->val[2] = (as >>24) & 0xff;
eval->val[3] = (as >>16) & 0xff;
eval->val[4] = (as >>8) & 0xff;
eval->val[5] = as & 0xff;
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
ecomm_type = ECOMMUNITY_ENCODE_AS4;
else
{
eval->val[0] = ECOMMUNITY_ENCODE_AS;
eval->val[1] = 0;
eval->val[2] = (as >>8) & 0xff;
eval->val[3] = as & 0xff;
eval->val[4] = (val >>24) & 0xff;
eval->val[5] = (val >>16) & 0xff;
eval->val[6] = (val >>8) & 0xff;
eval->val[7] = val & 0xff;
}
ecomm_type = ECOMMUNITY_ENCODE_AS;
if (ecommunity_encode(ecomm_type, 0, 1, as, ip, val, eval))
goto error;
*token = ecommunity_token_val;
return p;
@ -524,42 +508,35 @@ ecommunity_gettoken (const char *str, struct ecommunity_val *eval,
type = 0
keyword_include = 1
*/
struct ecommunity *
ecommunity_str2com (const char *str, int type, int keyword_included)
struct ecommunity *ecommunity_str2com(const char *str, int type,
int keyword_included)
{
struct ecommunity *ecom = NULL;
enum ecommunity_token token = ecommunity_token_unknown;
struct ecommunity_val eval;
int keyword = 0;
while ((str = ecommunity_gettoken (str, &eval, &token)))
{
switch (token)
{
while ((str = ecommunity_gettoken(str, &eval, &token))) {
switch (token) {
case ecommunity_token_rt:
case ecommunity_token_soo:
if (! keyword_included || keyword)
{
if (!keyword_included || keyword) {
if (ecom)
ecommunity_free(&ecom);
return NULL;
}
keyword = 1;
if (token == ecommunity_token_rt)
{
if (token == ecommunity_token_rt) {
type = ECOMMUNITY_ROUTE_TARGET;
}
if (token == ecommunity_token_soo)
{
if (token == ecommunity_token_soo) {
type = ECOMMUNITY_SITE_ORIGIN;
}
break;
case ecommunity_token_val:
if (keyword_included)
{
if (! keyword)
{
if (keyword_included) {
if (!keyword) {
if (ecom)
ecommunity_free(&ecom);
return NULL;
@ -581,6 +558,73 @@ ecommunity_str2com (const char *str, int type, int keyword_included)
return ecom;
}
static int ecommunity_rt_soo_str(char *buf, u_int8_t *pnt, int type,
int sub_type, int format)
{
int len = 0;
const char *prefix;
/* For parse Extended Community attribute tupple. */
struct ecommunity_as {
as_t as;
u_int32_t val;
} eas;
struct ecommunity_ip {
struct in_addr ip;
u_int16_t val;
} eip;
/* Determine prefix for string, if any. */
switch (format) {
case ECOMMUNITY_FORMAT_COMMUNITY_LIST:
prefix = (sub_type == ECOMMUNITY_ROUTE_TARGET ? "rt " : "soo ");
break;
case ECOMMUNITY_FORMAT_DISPLAY:
prefix = (sub_type == ECOMMUNITY_ROUTE_TARGET ? "RT:" : "SoO:");
break;
case ECOMMUNITY_FORMAT_ROUTE_MAP:
prefix = "";
break;
default:
prefix = "";
break;
}
/* Put string into buffer. */
if (type == ECOMMUNITY_ENCODE_AS4) {
eas.as = (*pnt++ << 24);
eas.as |= (*pnt++ << 16);
eas.as |= (*pnt++ << 8);
eas.as |= (*pnt++);
eas.val = (*pnt++ << 8);
eas.val |= (*pnt++);
len = sprintf(buf, "%s%u:%u", prefix, eas.as, eas.val);
} else if (type == ECOMMUNITY_ENCODE_AS) {
eas.as = (*pnt++ << 8);
eas.as |= (*pnt++);
eas.val = (*pnt++ << 24);
eas.val |= (*pnt++ << 16);
eas.val |= (*pnt++ << 8);
eas.val |= (*pnt++);
len = sprintf(buf, "%s%u:%u", prefix, eas.as, eas.val);
} else if (type == ECOMMUNITY_ENCODE_IP) {
memcpy(&eip.ip, pnt, 4);
pnt += 4;
eip.val = (*pnt++ << 8);
eip.val |= (*pnt++);
len = sprintf(buf, "%s%s:%u", prefix, inet_ntoa(eip.ip),
eip.val);
}
return len;
}
/* Convert extended community attribute to string.
Due to historical reason of industry standard implementation, there
@ -605,36 +649,20 @@ ecommunity_str2com (const char *str, int type, int keyword_included)
Filter is added to display only ECOMMUNITY_ROUTE_TARGET in some cases.
0 value displays all
*/
char *
ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
{
int i;
u_int8_t *pnt;
int encode = 0;
int type = 0;
int sub_type = 0;
#define ECOMMUNITY_STR_DEFAULT_LEN 27
int str_size;
int str_pnt;
char *str_buf;
const char *prefix;
int len = 0;
int first = 1;
/* For parse Extended Community attribute tupple. */
struct ecommunity_as
{
as_t as;
u_int32_t val;
} eas;
struct ecommunity_ip
{
struct in_addr ip;
u_int16_t val;
} eip;
if (ecom->size == 0)
{
if (ecom->size == 0) {
str_buf = XMALLOC(MTYPE_ECOMMUNITY_STR, 1);
str_buf[0] = '\0';
return str_buf;
@ -646,13 +674,14 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
str_buf[0] = '\0';
str_pnt = 0;
for (i = 0; i < ecom->size; i++)
{
for (i = 0; i < ecom->size; i++) {
int unk_ecom = 0;
/* Make it sure size is enough. */
while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size)
{
while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size) {
str_size *= 2;
str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size);
str_buf = XREALLOC(MTYPE_ECOMMUNITY_STR, str_buf,
str_size);
}
/* Space between each value. */
@ -662,137 +691,73 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
pnt = ecom->val + (i * 8);
/* High-order octet of type. */
encode = *pnt++;
type = *pnt++;
switch (encode)
{
case ECOMMUNITY_ENCODE_AS:
case ECOMMUNITY_ENCODE_IP:
case ECOMMUNITY_ENCODE_AS4:
break;
case ECOMMUNITY_ENCODE_OPAQUE:
if (type == ECOMMUNITY_ENCODE_AS || type == ECOMMUNITY_ENCODE_IP
|| type == ECOMMUNITY_ENCODE_AS4) {
/* Low-order octet of type. */
sub_type = *pnt++;
if (sub_type != ECOMMUNITY_ROUTE_TARGET
&& sub_type != ECOMMUNITY_SITE_ORIGIN)
unk_ecom = 1;
else
len = ecommunity_rt_soo_str(str_buf + str_pnt,
pnt, type, sub_type,
format);
} else if (type == ECOMMUNITY_ENCODE_OPAQUE) {
if (filter == ECOMMUNITY_ROUTE_TARGET)
{
continue;
}
if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP)
{
if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) {
uint16_t tunneltype;
memcpy(&tunneltype, pnt + 5, 2);
tunneltype = ntohs(tunneltype);
len = sprintf (str_buf + str_pnt, "ET:%d", tunneltype);
str_pnt += len;
first = 0;
continue;
}
len = sprintf (str_buf + str_pnt, "?");
str_pnt += len;
first = 0;
continue;
case ECOMMUNITY_ENCODE_EVPN:
len = sprintf(str_buf + str_pnt, "ET:%d",
tunneltype);
} else
unk_ecom = 1;
} else if (type == ECOMMUNITY_ENCODE_EVPN) {
if (filter == ECOMMUNITY_ROUTE_TARGET)
{
continue;
}
if (*pnt == ECOMMUNITY_SITE_ORIGIN)
{
if (*pnt == ECOMMUNITY_SITE_ORIGIN) {
char macaddr[6];
pnt++;
memcpy(&macaddr, pnt, 6);
len = sprintf(str_buf + str_pnt, "EVPN:%02x:%02x:%02x:%02x:%02x:%02x",
len = sprintf(
str_buf + str_pnt,
"EVPN:%02x:%02x:%02x:%02x:%02x:%02x",
macaddr[0], macaddr[1], macaddr[2],
macaddr[3], macaddr[4], macaddr[5]);
str_pnt += len;
first = 0;
continue;
}
} else if (*pnt
== ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
u_int32_t seqnum;
u_char flags = *++pnt;
memcpy(&seqnum, pnt + 2, 4);
seqnum = ntohl(seqnum);
if (flags
& ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY)
len = sprintf(str_buf + str_pnt,
"MM:%u, sticky MAC",
seqnum);
else
len = sprintf(str_buf + str_pnt,
"MM:%u", seqnum);
} else
unk_ecom = 1;
} else
unk_ecom = 1;
if (unk_ecom)
len = sprintf(str_buf + str_pnt, "?");
str_pnt += len;
first = 0;
continue;
default:
len = sprintf (str_buf + str_pnt, "?");
str_pnt += len;
first = 0;
continue;
}
/* Low-order octet of type. */
type = *pnt++;
if (type != ECOMMUNITY_ROUTE_TARGET && type != ECOMMUNITY_SITE_ORIGIN)
{
len = sprintf (str_buf + str_pnt, "?");
str_pnt += len;
first = 0;
continue;
}
switch (format)
{
case ECOMMUNITY_FORMAT_COMMUNITY_LIST:
prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "rt " : "soo ");
break;
case ECOMMUNITY_FORMAT_DISPLAY:
prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "RT:" : "SoO:");
break;
case ECOMMUNITY_FORMAT_ROUTE_MAP:
prefix = "";
break;
default:
prefix = "";
break;
}
/* Put string into buffer. */
if (encode == ECOMMUNITY_ENCODE_AS4)
{
eas.as = (*pnt++ << 24);
eas.as |= (*pnt++ << 16);
eas.as |= (*pnt++ << 8);
eas.as |= (*pnt++);
eas.val = (*pnt++ << 8);
eas.val |= (*pnt++);
len = sprintf( str_buf + str_pnt, "%s%u:%u", prefix,
eas.as, eas.val );
str_pnt += len;
first = 0;
}
if (encode == ECOMMUNITY_ENCODE_AS)
{
eas.as = (*pnt++ << 8);
eas.as |= (*pnt++);
eas.val = (*pnt++ << 24);
eas.val |= (*pnt++ << 16);
eas.val |= (*pnt++ << 8);
eas.val |= (*pnt++);
len = sprintf (str_buf + str_pnt, "%s%u:%u", prefix,
eas.as, eas.val);
str_pnt += len;
first = 0;
}
else if (encode == ECOMMUNITY_ENCODE_IP)
{
memcpy (&eip.ip, pnt, 4);
pnt += 4;
eip.val = (*pnt++ << 8);
eip.val |= (*pnt++);
len = sprintf (str_buf + str_pnt, "%s%s:%u", prefix,
inet_ntoa (eip.ip), eip.val);
str_pnt += len;
first = 0;
}
}
return str_buf;
}
int
ecommunity_match (const struct ecommunity *ecom1,
int ecommunity_match(const struct ecommunity *ecom1,
const struct ecommunity *ecom2)
{
int i = 0;
@ -808,11 +773,10 @@ ecommunity_match (const struct ecommunity *ecom1,
return 0;
/* Every community on com2 needs to be on com1 for this to match */
while (i < ecom1->size && j < ecom2->size)
{
while (i < ecom1->size && j < ecom2->size) {
if (memcmp(ecom1->val + i * ECOMMUNITY_SIZE,
ecom2->val + j * ECOMMUNITY_SIZE,
ECOMMUNITY_SIZE) == 0)
ecom2->val + j * ECOMMUNITY_SIZE, ECOMMUNITY_SIZE)
== 0)
j++;
i++;
}
@ -824,17 +788,16 @@ ecommunity_match (const struct ecommunity *ecom1,
}
/* return first occurence of type */
extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity *ecom, uint8_t type, uint8_t subtype)
extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *ecom,
uint8_t type, uint8_t subtype)
{
u_int8_t *p;
int c;
/* If the value already exists in the structure return 0. */
c = 0;
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
{
if(p == NULL)
{
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++) {
if (p == NULL) {
continue;
}
if (p[0] == type && p[1] == subtype)
@ -846,22 +809,20 @@ extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity *ecom,
/* remove ext. community matching type and subtype
* return 1 on success ( removed ), 0 otherwise (not present)
*/
extern int ecommunity_strip (struct ecommunity *ecom, uint8_t type, uint8_t subtype)
extern int ecommunity_strip(struct ecommunity *ecom, uint8_t type,
uint8_t subtype)
{
u_int8_t *p;
int c, found = 0;
/* When this is fist value, just add it. */
if (ecom == NULL || ecom->val == NULL)
{
if (ecom == NULL || ecom->val == NULL) {
return 0;
}
/* If the value already exists in the structure return 0. */
c = 0;
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
{
if (p[0] == type && p[1] == subtype)
{
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++) {
if (p[0] == type && p[1] == subtype) {
found = 1;
break;
}

View File

@ -32,12 +32,15 @@
#define ECOMMUNITY_ROUTE_TARGET 0x02
#define ECOMMUNITY_SITE_ORIGIN 0x03
/* Low-order octet of the Extended Communities type field for EVPN types */
#define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY 0x00
#define ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL 0x01
#define ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT 0x02
#define ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC 0x03
#define ECOMMUNITY_EVPN_SUBTYPE_DEF_GW 0x0d
#define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01
/* Low-order octet of the Extended Communities type field for OPAQUE types */
#define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP 0x0c
@ -53,8 +56,7 @@
#define ECOMMUNITY_FLAG_NON_TRANSITIVE 0x40
/* Extended Communities attribute. */
struct ecommunity
{
struct ecommunity {
/* Reference counter. */
unsigned long refcnt;
@ -69,19 +71,64 @@ struct ecommunity
};
/* Extended community value is eight octet. */
struct ecommunity_val
{
struct ecommunity_val {
char val[ECOMMUNITY_SIZE];
};
#define ecom_length(X) ((X)->size * ECOMMUNITY_SIZE)
/*
* Encode BGP Route Target AS:nn.
*/
static inline void encode_route_target_as(as_t as, u_int32_t val,
struct ecommunity_val *eval)
{
eval->val[0] = ECOMMUNITY_ENCODE_AS;
eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
eval->val[2] = (as >> 8) & 0xff;
eval->val[3] = as & 0xff;
eval->val[4] = (val >> 24) & 0xff;
eval->val[5] = (val >> 16) & 0xff;
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
/*
* Encode BGP Route Target IP:nn.
*/
static inline void encode_route_target_ip(struct in_addr ip, u_int16_t val,
struct ecommunity_val *eval)
{
eval->val[0] = ECOMMUNITY_ENCODE_IP;
eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
memcpy(&eval->val[2], &ip, sizeof(struct in_addr));
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
/*
* Encode BGP Route Target AS4:nn.
*/
static inline void encode_route_target_as4(as_t as, u_int16_t val,
struct ecommunity_val *eval)
{
eval->val[0] = ECOMMUNITY_ENCODE_AS4;
eval->val[1] = ECOMMUNITY_ROUTE_TARGET;
eval->val[2] = (as >> 24) & 0xff;
eval->val[3] = (as >> 16) & 0xff;
eval->val[4] = (as >> 8) & 0xff;
eval->val[5] = as & 0xff;
eval->val[6] = (val >> 8) & 0xff;
eval->val[7] = val & 0xff;
}
extern void ecommunity_init(void);
extern void ecommunity_finish(void);
extern void ecommunity_free(struct ecommunity **);
extern struct ecommunity *ecommunity_parse(u_int8_t *, u_short);
extern struct ecommunity *ecommunity_dup(struct ecommunity *);
extern struct ecommunity *ecommunity_merge (struct ecommunity *, struct ecommunity *);
extern struct ecommunity *ecommunity_merge(struct ecommunity *,
struct ecommunity *);
extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
extern struct ecommunity *ecommunity_intern(struct ecommunity *);
extern int ecommunity_cmp(const void *, const void *);
@ -89,14 +136,18 @@ extern void ecommunity_unintern (struct ecommunity **);
extern unsigned int ecommunity_hash_make(void *);
extern struct ecommunity *ecommunity_str2com(const char *, int, int);
extern char *ecommunity_ecom2str(struct ecommunity *, int, int);
extern int ecommunity_match (const struct ecommunity *, const struct ecommunity *);
extern int ecommunity_match(const struct ecommunity *,
const struct ecommunity *);
extern char *ecommunity_str(struct ecommunity *);
extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity *, uint8_t, uint8_t );
extern int ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval);
extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *,
uint8_t, uint8_t);
extern int ecommunity_add_val(struct ecommunity *ecom,
struct ecommunity_val *eval);
/* for vpn */
extern struct ecommunity *ecommunity_new(void);
extern int ecommunity_add_val(struct ecommunity *, struct ecommunity_val *);
extern int ecommunity_strip (struct ecommunity *ecom, uint8_t type, uint8_t subtype);
extern int ecommunity_strip(struct ecommunity *ecom, uint8_t type,
uint8_t subtype);
extern struct ecommunity *ecommunity_new(void);
#endif /* _QUAGGA_BGP_ECOMMUNITY_H */

File diff suppressed because it is too large Load Diff

View File

@ -19,157 +19,115 @@
#ifndef _QUAGGA_BGP_ENCAP_TLV_H
#define _QUAGGA_BGP_ENCAP_TLV_H
/***********************************************************************
* TUNNEL TYPE-SPECIFIC TLV ENCODE
***********************************************************************/
extern void
bgp_encap_type_l2tpv3overip_to_tlv(
struct bgp_encap_type_l2tpv3_over_ip *bet,
bgp_encap_type_l2tpv3overip_to_tlv(struct bgp_encap_type_l2tpv3_over_ip *bet,
struct attr *attr);
extern void
bgp_encap_type_gre_to_tlv(
struct bgp_encap_type_gre *bet,
extern void bgp_encap_type_gre_to_tlv(struct bgp_encap_type_gre *bet,
struct attr *attr);
extern void
bgp_encap_type_ip_in_ip_to_tlv(
struct bgp_encap_type_ip_in_ip *bet,
extern void bgp_encap_type_ip_in_ip_to_tlv(struct bgp_encap_type_ip_in_ip *bet,
struct attr *attr);
extern void
bgp_encap_type_transmit_tunnel_endpoint(
struct bgp_encap_type_transmit_tunnel_endpoint *bet,
struct attr *attr);
extern void bgp_encap_type_transmit_tunnel_endpoint(
struct bgp_encap_type_transmit_tunnel_endpoint *bet, struct attr *attr);
extern void
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
struct bgp_encap_type_ipsec_in_tunnel_mode *bet,
struct attr *attr);
extern void bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
struct bgp_encap_type_ipsec_in_tunnel_mode *bet, struct attr *attr);
extern void
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
extern void bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
extern void bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet,
struct attr *attr);
extern void
bgp_encap_type_pbb_to_tlv(
struct bgp_encap_type_pbb *bet,
extern void bgp_encap_type_pbb_to_tlv(struct bgp_encap_type_pbb *bet,
struct attr *attr);
extern void bgp_encap_type_vxlan_to_tlv(struct bgp_encap_type_vxlan *bet,
struct attr *attr);
extern void bgp_encap_type_nvgre_to_tlv(struct bgp_encap_type_nvgre *bet,
struct attr *attr);
extern void bgp_encap_type_mpls_to_tlv(struct bgp_encap_type_mpls *bet,
struct attr *attr);
extern void
bgp_encap_type_vxlan_to_tlv(
struct bgp_encap_type_vxlan *bet,
bgp_encap_type_mpls_in_gre_to_tlv(struct bgp_encap_type_mpls_in_gre *bet,
struct attr *attr);
extern void
bgp_encap_type_nvgre_to_tlv(
struct bgp_encap_type_nvgre *bet,
bgp_encap_type_vxlan_gpe_to_tlv(struct bgp_encap_type_vxlan_gpe *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_to_tlv(
struct bgp_encap_type_mpls *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_in_gre_to_tlv(
struct bgp_encap_type_mpls_in_gre *bet,
struct attr *attr);
extern void
bgp_encap_type_vxlan_gpe_to_tlv(
struct bgp_encap_type_vxlan_gpe *bet,
struct attr *attr);
extern void
bgp_encap_type_mpls_in_udp_to_tlv(
struct bgp_encap_type_mpls_in_udp *bet,
bgp_encap_type_mpls_in_udp_to_tlv(struct bgp_encap_type_mpls_in_udp *bet,
struct attr *attr);
/***********************************************************************
* TUNNEL TYPE-SPECIFIC TLV DECODE
***********************************************************************/
extern int
tlv_to_bgp_encap_type_l2tpv3overip(
extern int tlv_to_bgp_encap_type_l2tpv3overip(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_l2tpv3_over_ip *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_gre(
extern int tlv_to_bgp_encap_type_gre(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_gre *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_ip_in_ip(
extern int tlv_to_bgp_encap_type_ip_in_ip(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_ip_in_ip *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
extern int tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_transmit_tunnel_endpoint *bet);
extern int
tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
extern int tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_ipsec_in_tunnel_mode *bet); /* caller-allocated */
extern int
tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
extern int tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet);
extern int
tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
extern int tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet);
extern int
tlv_to_bgp_encap_type_vxlan(
struct bgp_attr_encap_subtlv *stlv,
extern int tlv_to_bgp_encap_type_vxlan(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_vxlan *bet);
extern int
tlv_to_bgp_encap_type_nvgre(
struct bgp_attr_encap_subtlv *stlv,
extern int tlv_to_bgp_encap_type_nvgre(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_nvgre *bet);
extern int
tlv_to_bgp_encap_type_mpls(
struct bgp_attr_encap_subtlv *stlv,
extern int tlv_to_bgp_encap_type_mpls(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls *bet);
extern int tlv_to_bgp_encap_type_mpls(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls *bet);
extern int
tlv_to_bgp_encap_type_mpls(
struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls *bet);
extern int
tlv_to_bgp_encap_type_mpls_in_gre(
struct bgp_attr_encap_subtlv *stlv,
tlv_to_bgp_encap_type_mpls_in_gre(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls_in_gre *bet);
extern int
tlv_to_bgp_encap_type_vxlan_gpe(
struct bgp_attr_encap_subtlv *stlv,
tlv_to_bgp_encap_type_vxlan_gpe(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_vxlan_gpe *bet);
extern int
tlv_to_bgp_encap_type_mpls_in_udp(
struct bgp_attr_encap_subtlv *stlv,
tlv_to_bgp_encap_type_mpls_in_udp(struct bgp_attr_encap_subtlv *stlv,
struct bgp_encap_type_mpls_in_udp *bet);
extern int
tlv_to_bgp_encap_type_pbb(
extern int tlv_to_bgp_encap_type_pbb(
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
struct bgp_encap_type_pbb *bet); /* caller-allocated */

View File

@ -19,7 +19,11 @@
#ifndef _QUAGGA_BGP_ENCAP_TYPES_H
#define _QUAGGA_BGP_ENCAP_TYPES_H
/* from http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#tunnel-types */
#include "bgpd/bgp_ecommunity.h"
/* from
* http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#tunnel-types
*/
typedef enum {
BGP_ENCAP_TYPE_RESERVED = 0,
BGP_ENCAP_TYPE_L2TPV3_OVER_IP = 1,
@ -43,7 +47,8 @@ typedef enum {
BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE = 2,
BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA = 3,
BGP_ENCAP_SUBTLV_TYPE_COLOR = 4,
BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT=6 /* speculative, IANA assignment TBD */
BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT =
6 /* speculative, IANA assignment TBD */
} bgp_encap_subtlv_types;
/*
@ -213,4 +218,14 @@ struct bgp_encap_type_pbb {
struct bgp_tea_subtlv_encap_pbb st_encap;
};
static inline void encode_encap_extcomm(bgp_encap_types tnl_type,
struct ecommunity_val *eval)
{
memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE;
eval->val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP;
eval->val[6] = ((tnl_type) >> 8) & 0xff;
eval->val[7] = (tnl_type)&0xff;
}
#endif /* _QUAGGA_BGP_ENCAP_TYPES_H */

File diff suppressed because it is too large Load Diff

View File

@ -21,20 +21,33 @@
#ifndef _QUAGGA_BGP_EVPN_H
#define _QUAGGA_BGP_EVPN_H
#include "vxlan.h"
#define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
extern char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len);
extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len);
extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
struct prefix_rd *prd, mpls_label_t *label,
struct attr *attr, int addpath_encode,
u_int32_t addpath_tx_id);
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
struct bgp_nlri *packet, int withdraw);
extern void
bgp_packet_mpattr_route_type_5(struct stream *s,
struct prefix *p, struct prefix_rd *prd,
u_char * label, struct attr *attr);
/* EVPN route types as per RFC7432 and
* as per draft-ietf-bess-evpn-prefix-advertisement-02
*/
#define EVPN_ETHERNET_AUTO_DISCOVERY 1
#define EVPN_MACIP_ADVERTISEMENT 2
#define EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG 3
#define EVPN_ETHERNET_SEGMENT 4
#define EVPN_IP_PREFIX 5
extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
struct prefix *p, struct bgp_info *ri);
extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
struct prefix *p, struct bgp_info *ri);
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
struct ethaddr *mac, struct ipaddr *ip);
extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
struct ethaddr *mac, struct ipaddr *ip,
u_char sticky);
extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
struct in_addr originator_ip);
extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
extern void bgp_evpn_cleanup(struct bgp *bgp);
extern void bgp_evpn_init(struct bgp *bgp);
#endif /* _QUAGGA_BGP_EVPN_H */

213
bgpd/bgp_evpn_private.h Normal file
View File

@ -0,0 +1,213 @@
/* BGP EVPN internal definitions
* Copyright (C) 2017 Cumulus Networks, Inc.
*
* This file is part of FRR.
*
* FRR is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* FRR is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRR; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _BGP_EVPN_PRIVATE_H
#define _BGP_EVPN_PRIVATE_H
#include "vxlan.h"
#include "zebra.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
/* EVPN prefix lengths. */
#define EVPN_TYPE_2_ROUTE_PREFIXLEN 224
#define EVPN_TYPE_3_ROUTE_PREFIXLEN 224
/* EVPN route types. */
typedef enum {
BGP_EVPN_AD_ROUTE = 1, /* Ethernet Auto-Discovery (A-D) route */
BGP_EVPN_MAC_IP_ROUTE, /* MAC/IP Advertisement route */
BGP_EVPN_IMET_ROUTE, /* Inclusive Multicast Ethernet Tag route */
BGP_EVPN_ES_ROUTE, /* Ethernet Segment route */
BGP_EVPN_IP_PREFIX_ROUTE, /* IP Prefix route */
} bgp_evpn_route_type;
/*
* Hash table of EVIs. Right now, the only type of EVI supported is with
* VxLAN encapsulation, hence each EVI corresponds to a L2 VNI.
* The VNIs are not "created" through BGP but through some other interface
* on the system. This table stores VNIs that BGP comes to know as present
* on the system (through interaction with zebra) as well as pre-configured
* VNIs (which need to be defined in the system to become "live").
*/
struct bgpevpn {
vni_t vni;
u_int32_t flags;
#define VNI_FLAG_CFGD 0x1 /* VNI is user configured */
#define VNI_FLAG_LIVE 0x2 /* VNI is "live" */
#define VNI_FLAG_RD_CFGD 0x4 /* RD is user configured. */
#define VNI_FLAG_IMPRT_CFGD 0x8 /* Import RT is user configured */
#define VNI_FLAG_EXPRT_CFGD 0x10 /* Export RT is user configured */
/* Id for deriving the RD automatically for this VNI */
u_int16_t rd_id;
/* RD for this VNI. */
struct prefix_rd prd;
/* Route type 3 field */
struct in_addr originator_ip;
/* Import and Export RTs. */
struct list *import_rtl;
struct list *export_rtl;
/* Route table for EVPN routes for this VNI. */
struct bgp_table *route_table;
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(bgpevpn)
/* Mapping of Import RT to VNIs.
* The Import RTs of all VNIs are maintained in a hash table with each
* RT linking to all VNIs that will import routes matching this RT.
*/
struct irt_node {
/* RT */
struct ecommunity_val rt;
/* List of VNIs importing routes matching this RT. */
struct list *vnis;
};
#define RT_TYPE_IMPORT 1
#define RT_TYPE_EXPORT 2
#define RT_TYPE_BOTH 3
static inline int is_vni_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD));
}
static inline int is_vni_live(struct bgpevpn *vpn)
{
return (CHECK_FLAG(vpn->flags, VNI_FLAG_LIVE));
}
static inline int is_rd_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG(vpn->flags, VNI_FLAG_RD_CFGD));
}
static inline int bgp_evpn_rd_matches_existing(struct bgpevpn *vpn,
struct prefix_rd *prd)
{
return (memcmp(&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0);
}
static inline int is_import_rt_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD));
}
static inline int is_export_rt_configured(struct bgpevpn *vpn)
{
return (CHECK_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD));
}
static inline int is_vni_param_configured(struct bgpevpn *vpn)
{
return (is_rd_configured(vpn) || is_import_rt_configured(vpn)
|| is_export_rt_configured(vpn));
}
static inline void vni2label(vni_t vni, mpls_label_t *label)
{
u_char *tag = (u_char *)label;
tag[0] = (vni >> 16) & 0xFF;
tag[1] = (vni >> 8) & 0xFF;
tag[2] = vni & 0xFF;
}
static inline vni_t label2vni(mpls_label_t *label)
{
u_char *tag = (u_char *)label;
vni_t vni;
vni = ((u_int32_t)*tag++ << 16);
vni |= (u_int32_t)*tag++ << 8;
vni |= (u_int32_t)(*tag & 0xFF);
return vni;
}
static inline void encode_mac_mobility_extcomm(int static_mac, u_int32_t seq,
struct ecommunity_val *eval)
{
memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY;
if (static_mac)
eval->val[2] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY;
eval->val[4] = (seq >> 24) & 0xff;
eval->val[5] = (seq >> 16) & 0xff;
eval->val[6] = (seq >> 8) & 0xff;
eval->val[7] = seq & 0xff;
}
static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
struct ethaddr *mac,
struct ipaddr *ip)
{
memset(p, 0, sizeof(struct prefix_evpn));
p->family = AF_ETHERNET;
p->prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
memcpy(&p->prefix.mac.octet, mac->octet, ETHER_ADDR_LEN);
p->prefix.ip.ipa_type = IPADDR_NONE;
if (ip)
memcpy(&p->prefix.ip, ip, sizeof(*ip));
}
static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
struct in_addr originator_ip)
{
memset(p, 0, sizeof(struct prefix_evpn));
p->family = AF_ETHERNET;
p->prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
p->prefix.ip.ipa_type = IPADDR_V4;
p->prefix.ip.ipaddr_v4 = originator_ip;
}
extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
int withdraw);
extern int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn);
extern int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn);
extern void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn);
extern void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_derive_auto_rt_import(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp,
struct bgpevpn *vpn);
extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn);
extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni);
extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
struct in_addr originator_ip);
extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn);
#endif /* _BGP_EVPN_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@
#ifndef _FRR_BGP_EVPN_VTY_H
#define _FRR_BGP_EVPN_VTY_H
extern void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp,
afi_t afi, safi_t safi, int *write);
extern void bgp_ethernetvpn_init(void);
#define L2VPN_HELP_STR "Layer 2 Virtual Private Network\n"

View File

@ -33,15 +33,13 @@
#include "bgpd/bgp_filter.h"
/* List of AS filter list. */
struct as_list_list
{
struct as_list_list {
struct as_list *head;
struct as_list *tail;
};
/* AS path filter master. */
struct as_list_master
{
struct as_list_master {
/* List of access_list which name is number. */
struct as_list_list num;
@ -56,8 +54,7 @@ struct as_list_master
};
/* Element of AS path filter. */
struct as_filter
{
struct as_filter {
struct as_filter *next;
struct as_filter *prev;
@ -68,8 +65,7 @@ struct as_filter
};
/* AS path filter list. */
struct as_list
{
struct as_list {
char *name;
enum access_type type;
@ -83,24 +79,19 @@ struct as_list
/* ip as-path access-list 10 permit AS1. */
static struct as_list_master as_list_master =
{
{NULL, NULL},
static struct as_list_master as_list_master = {{NULL, NULL},
{NULL, NULL},
NULL,
NULL
};
NULL};
/* Allocate new AS filter. */
static struct as_filter *
as_filter_new (void)
static struct as_filter *as_filter_new(void)
{
return XCALLOC(MTYPE_AS_FILTER, sizeof(struct as_filter));
}
/* Free allocated AS filter. */
static void
as_filter_free (struct as_filter *asfilter)
static void as_filter_free(struct as_filter *asfilter)
{
if (asfilter->reg)
bgp_regex_free(asfilter->reg);
@ -110,8 +101,8 @@ as_filter_free (struct as_filter *asfilter)
}
/* Make new AS filter. */
static struct as_filter *
as_filter_make (regex_t *reg, const char *reg_str, enum as_filter_type type)
static struct as_filter *as_filter_make(regex_t *reg, const char *reg_str,
enum as_filter_type type)
{
struct as_filter *asfilter;
@ -123,8 +114,8 @@ as_filter_make (regex_t *reg, const char *reg_str, enum as_filter_type type)
return asfilter;
}
static struct as_filter *
as_filter_lookup (struct as_list *aslist, const char *reg_str,
static struct as_filter *as_filter_lookup(struct as_list *aslist,
const char *reg_str,
enum as_filter_type type)
{
struct as_filter *asfilter;
@ -135,8 +126,8 @@ as_filter_lookup (struct as_list *aslist, const char *reg_str,
return NULL;
}
static void
as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
static void as_list_filter_add(struct as_list *aslist,
struct as_filter *asfilter)
{
asfilter->next = NULL;
asfilter->prev = aslist->tail;
@ -150,12 +141,10 @@ as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
/* Run hook function. */
if (as_list_master.add_hook)
(*as_list_master.add_hook)(aslist->name);
}
/* Lookup as_list from list of as_list by name. */
struct as_list *
as_list_lookup (const char *name)
struct as_list *as_list_lookup(const char *name)
{
struct as_list *aslist;
@ -173,17 +162,14 @@ as_list_lookup (const char *name)
return NULL;
}
static struct as_list *
as_list_new (void)
static struct as_list *as_list_new(void)
{
return XCALLOC(MTYPE_AS_LIST, sizeof(struct as_list));
}
static void
as_list_free (struct as_list *aslist)
{
if (aslist->name)
static void as_list_free(struct as_list *aslist)
{
if (aslist->name) {
XFREE(MTYPE_AS_STR, aslist->name);
aslist->name = NULL;
}
@ -192,8 +178,7 @@ as_list_free (struct as_list *aslist)
/* Insert new AS list to list of as_list. Each as_list is sorted by
the name. */
static struct as_list *
as_list_insert (const char *name)
static struct as_list *as_list_insert(const char *name)
{
size_t i;
long number;
@ -208,8 +193,7 @@ as_list_insert (const char *name)
/* If name is made by all digit character. We treat it as
number. */
for (number = 0, i = 0; i < strlen (name); i++)
{
for (number = 0, i = 0; i < strlen(name); i++) {
if (isdigit((int)name[i]))
number = (number * 10) + (name[i] - '0');
else
@ -217,8 +201,7 @@ as_list_insert (const char *name)
}
/* In case of name is all digit character */
if (i == strlen (name))
{
if (i == strlen(name)) {
aslist->type = ACCESS_TYPE_NUMBER;
/* Set access_list to number list. */
@ -227,9 +210,7 @@ as_list_insert (const char *name)
for (point = list->head; point; point = point->next)
if (atol(point->name) >= number)
break;
}
else
{
} else {
aslist->type = ACCESS_TYPE_STRING;
/* Set access_list to string list. */
@ -242,15 +223,13 @@ as_list_insert (const char *name)
}
/* In case of this is the first element of master. */
if (list->head == NULL)
{
if (list->head == NULL) {
list->head = list->tail = aslist;
return aslist;
}
/* In case of insertion is made at the tail of access_list. */
if (point == NULL)
{
if (point == NULL) {
aslist->prev = list->tail;
list->tail->next = aslist;
list->tail = aslist;
@ -258,8 +237,7 @@ as_list_insert (const char *name)
}
/* In case of insertion is made at the head of access_list. */
if (point == list->head)
{
if (point == list->head) {
aslist->next = list->head;
list->head->prev = aslist;
list->head = aslist;
@ -277,8 +255,7 @@ as_list_insert (const char *name)
return aslist;
}
static struct as_list *
as_list_get (const char *name)
static struct as_list *as_list_get(const char *name)
{
struct as_list *aslist;
@ -289,11 +266,9 @@ as_list_get (const char *name)
return aslist;
}
static const char *
filter_type_str (enum as_filter_type type)
{
switch (type)
static const char *filter_type_str(enum as_filter_type type)
{
switch (type) {
case AS_FILTER_PERMIT:
return "permit";
case AS_FILTER_DENY:
@ -303,14 +278,12 @@ filter_type_str (enum as_filter_type type)
}
}
static void
as_list_delete (struct as_list *aslist)
static void as_list_delete(struct as_list *aslist)
{
struct as_list_list *list;
struct as_filter *filter, *next;
for (filter = aslist->head; filter; filter = next)
{
for (filter = aslist->head; filter; filter = next) {
next = filter->next;
as_filter_free(filter);
}
@ -333,8 +306,7 @@ as_list_delete (struct as_list *aslist)
as_list_free(aslist);
}
static int
as_list_empty (struct as_list *aslist)
static int as_list_empty(struct as_list *aslist)
{
if (aslist->head == NULL && aslist->tail == NULL)
return 1;
@ -342,8 +314,8 @@ as_list_empty (struct as_list *aslist)
return 0;
}
static void
as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
static void as_list_filter_delete(struct as_list *aslist,
struct as_filter *asfilter)
{
char *name = XSTRDUP(MTYPE_AS_STR, aslist->name);
@ -370,8 +342,7 @@ as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
XFREE(MTYPE_AS_STR, name);
}
static int
as_filter_match (struct as_filter *asfilter, struct aspath *aspath)
static int as_filter_match(struct as_filter *asfilter, struct aspath *aspath)
{
if (bgp_regexec(asfilter->reg, aspath) != REG_NOMATCH)
return 1;
@ -379,8 +350,7 @@ as_filter_match (struct as_filter *asfilter, struct aspath *aspath)
}
/* Apply AS path filter to AS. */
enum as_filter_type
as_list_apply (struct as_list *aslist, void *object)
enum as_filter_type as_list_apply(struct as_list *aslist, void *object)
{
struct as_filter *asfilter;
struct aspath *aspath;
@ -390,8 +360,7 @@ as_list_apply (struct as_list *aslist, void *object)
if (aslist == NULL)
return AS_FILTER_DENY;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
if (as_filter_match(asfilter, aspath))
return asfilter->type;
}
@ -399,26 +368,22 @@ as_list_apply (struct as_list *aslist, void *object)
}
/* Add hook function. */
void
as_list_add_hook (void (*func) (char *))
void as_list_add_hook(void (*func)(char *))
{
as_list_master.add_hook = func;
}
/* Delete hook function. */
void
as_list_delete_hook (void (*func) (const char *))
void as_list_delete_hook(void (*func)(const char *))
{
as_list_master.delete_hook = func;
}
static int
as_list_dup_check (struct as_list *aslist, struct as_filter *new)
static int as_list_dup_check(struct as_list *aslist, struct as_filter *new)
{
struct as_filter *asfilter;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
if (asfilter->type == new->type
&& strcmp(asfilter->reg_str, new->reg_str) == 0)
return 1;
@ -445,21 +410,22 @@ DEFUN (ip_as_path,
char *regstr;
/* Retrieve access list name */
char *alname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
char *alname =
argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
/* Check the filter type. */
type = argv_find (argv, argc, "deny", &idx) ? AS_FILTER_DENY : AS_FILTER_PERMIT;
type = argv_find(argv, argc, "deny", &idx) ? AS_FILTER_DENY
: AS_FILTER_PERMIT;
/* Check AS path regex. */
argv_find(argv, argc, "LINE", &idx);
regstr = argv_concat(argv, argc, idx);
regex = bgp_regcomp(regstr);
if (!regex)
{
vty_outln (vty, "can't compile regexp %s", regstr);
if (!regex) {
vty_out(vty, "can't compile regexp %s\n", regstr);
XFREE(MTYPE_TMP, regstr);
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
}
asfilter = as_filter_make(regex, regstr, type);
@ -497,14 +463,15 @@ DEFUN (no_ip_as_path,
char *regstr;
regex_t *regex;
char *aslistname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
char *aslistname =
argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
/* Lookup AS list from AS path list. */
aslist = as_list_lookup(aslistname);
if (aslist == NULL)
{
vty_outln (vty, "ip as-path access-list %s doesn't exist",aslistname);
return CMD_WARNING;
if (aslist == NULL) {
vty_out(vty, "ip as-path access-list %s doesn't exist\n",
aslistname);
return CMD_WARNING_CONFIG_FAILED;
}
/* Check the filter type. */
@ -512,10 +479,9 @@ DEFUN (no_ip_as_path,
type = AS_FILTER_PERMIT;
else if (argv_find(argv, argc, "deny", &idx))
type = AS_FILTER_DENY;
else
{
vty_outln (vty, "filter type must be [permit|deny]");
return CMD_WARNING;
else {
vty_out(vty, "filter type must be [permit|deny]\n");
return CMD_WARNING_CONFIG_FAILED;
}
/* Compile AS path. */
@ -523,11 +489,10 @@ DEFUN (no_ip_as_path,
regstr = argv_concat(argv, argc, idx);
regex = bgp_regcomp(regstr);
if (!regex)
{
vty_outln (vty, "can't compile regexp %s", regstr);
if (!regex) {
vty_out(vty, "can't compile regexp %s\n", regstr);
XFREE(MTYPE_TMP, regstr);
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
}
/* Lookup asfilter. */
@ -536,10 +501,9 @@ DEFUN (no_ip_as_path,
XFREE(MTYPE_TMP, regstr);
bgp_regex_free(regex);
if (asfilter == NULL)
{
vty_out (vty, VTYNL);
return CMD_WARNING;
if (asfilter == NULL) {
vty_out(vty, "\n");
return CMD_WARNING_CONFIG_FAILED;
}
as_list_filter_delete(aslist, asfilter);
@ -560,11 +524,10 @@ DEFUN (no_ip_as_path_all,
struct as_list *aslist;
aslist = as_list_lookup(argv[idx_word]->arg);
if (aslist == NULL)
{
vty_outln (vty, "ip as-path access-list %s doesn't exist",
if (aslist == NULL) {
vty_out(vty, "ip as-path access-list %s doesn't exist\n",
argv[idx_word]->arg);
return CMD_WARNING;
return CMD_WARNING_CONFIG_FAILED;
}
as_list_delete(aslist);
@ -576,44 +539,41 @@ DEFUN (no_ip_as_path_all,
return CMD_SUCCESS;
}
static void
as_list_show (struct vty *vty, struct as_list *aslist)
static void as_list_show(struct vty *vty, struct as_list *aslist)
{
struct as_filter *asfilter;
vty_outln (vty, "AS path access list %s", aslist->name);
vty_out(vty, "AS path access list %s\n", aslist->name);
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_outln (vty, " %s %s", filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next) {
vty_out(vty, " %s %s\n", filter_type_str(asfilter->type),
asfilter->reg_str);
}
}
static void
as_list_show_all (struct vty *vty)
static void as_list_show_all(struct vty *vty)
{
struct as_list *aslist;
struct as_filter *asfilter;
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
{
vty_outln (vty, "AS path access list %s", aslist->name);
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next) {
vty_out(vty, "AS path access list %s\n", aslist->name);
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_outln (vty, " %s %s", filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, " %s %s\n",
filter_type_str(asfilter->type),
asfilter->reg_str);
}
}
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
{
vty_outln (vty, "AS path access list %s", aslist->name);
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next) {
vty_out(vty, "AS path access list %s\n", aslist->name);
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_outln (vty, " %s %s", filter_type_str (asfilter->type),
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, " %s %s\n",
filter_type_str(asfilter->type),
asfilter->reg_str);
}
}
@ -648,26 +608,25 @@ DEFUN (show_ip_as_path_access_list_all,
return CMD_SUCCESS;
}
static int
config_write_as_list (struct vty *vty)
static int config_write_as_list(struct vty *vty)
{
struct as_list *aslist;
struct as_filter *asfilter;
int write = 0;
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_outln (vty, "ip as-path access-list %s %s %s",
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, "ip as-path access-list %s %s %s\n",
aslist->name, filter_type_str(asfilter->type),
asfilter->reg_str);
write++;
}
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_outln (vty, "ip as-path access-list %s %s %s",
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, "ip as-path access-list %s %s %s\n",
aslist->name, filter_type_str(asfilter->type),
asfilter->reg_str);
write++;
@ -675,16 +634,10 @@ config_write_as_list (struct vty *vty)
return write;
}
static struct cmd_node as_list_node =
{
AS_LIST_NODE,
"",
1
};
static struct cmd_node as_list_node = {AS_LIST_NODE, "", 1};
/* Register functions. */
void
bgp_filter_init (void)
void bgp_filter_init(void)
{
install_node(&as_list_node, config_write_as_list);
@ -696,20 +649,17 @@ bgp_filter_init (void)
install_element(VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
}
void
bgp_filter_reset (void)
void bgp_filter_reset(void)
{
struct as_list *aslist;
struct as_list *next;
for (aslist = as_list_master.num.head; aslist; aslist = next)
{
for (aslist = as_list_master.num.head; aslist; aslist = next) {
next = aslist->next;
as_list_delete(aslist);
}
for (aslist = as_list_master.str.head; aslist; aslist = next)
{
for (aslist = as_list_master.str.head; aslist; aslist = next) {
next = aslist->next;
as_list_delete(aslist);
}

View File

@ -21,11 +21,7 @@
#ifndef _QUAGGA_BGP_FILTER_H
#define _QUAGGA_BGP_FILTER_H
enum as_filter_type
{
AS_FILTER_DENY,
AS_FILTER_PERMIT
};
enum as_filter_type { AS_FILTER_DENY, AS_FILTER_PERMIT };
extern void bgp_filter_init(void);
extern void bgp_filter_reset(void);

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,8 @@
#define BGP_EVENT_ADD(P, E) \
do { \
if ((P)->status != Deleted) \
thread_add_event (bm->master, bgp_event, (P), (E), NULL); \
thread_add_event(bm->master, bgp_event, (P), (E), \
NULL); \
} while (0)
#define BGP_EVENT_FLUSH(P) \

View File

@ -41,8 +41,7 @@
extern struct zclient *zclient;
int
bgp_parse_fec_update (void)
int bgp_parse_fec_update(void)
{
struct stream *s;
struct bgp_node *rn;
@ -63,34 +62,30 @@ bgp_parse_fec_update (void)
/* hack for the bgp instance & SAFI = have to send/receive it */
afi = family2afi(p.family);
safi = SAFI_LABELED_UNICAST;
safi = SAFI_UNICAST;
bgp = bgp_get_default();
if (!bgp)
{
if (!bgp) {
zlog_debug("no default bgp instance");
return -1;
}
table = bgp->rib[afi][safi];
if (!table)
{
zlog_debug("no %u labeled-unicast table", p.family);
if (!table) {
zlog_debug("no %u unicast table", p.family);
return -1;
}
rn = bgp_node_lookup(table, &p);
if (!rn)
{
if (!rn) {
zlog_debug("no node for the prefix");
return -1;
}
/* treat it as implicit withdraw - the label is invalid */
if (label == MPLS_INVALID_LABEL)
bgp_unset_valid_label(rn->local_label);
else
{
label_ntop(label, 1, rn->local_label);
bgp_set_valid_label(rn->local_label);
bgp_unset_valid_label(&rn->local_label);
else {
label_ntop(label, 1, &rn->local_label);
bgp_set_valid_label(&rn->local_label);
}
SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
bgp_unlock_node(rn);
@ -98,22 +93,23 @@ bgp_parse_fec_update (void)
return 1;
}
u_char *
bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
afi_t afi, safi_t safi)
mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
struct peer *to, afi_t afi, safi_t safi)
{
struct peer *from;
u_char *remote_label;
mpls_label_t remote_label;
int reflect;
if (!rn || !ri || !to)
return NULL;
return MPLS_INVALID_LABEL;
remote_label = ri->extra ? ri->extra->tag : NULL;
remote_label = ri->extra ? ri->extra->label : MPLS_INVALID_LABEL;
from = ri->peer;
reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
reflect =
((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
if (reflect && !CHECK_FLAG(to->af_flags[afi][safi],
if (reflect
&& !CHECK_FLAG(to->af_flags[afi][safi],
PEER_FLAG_FORCE_NEXTHOP_SELF))
return remote_label;
@ -123,9 +119,7 @@ bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
return rn->local_label;
}
void
bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
int reg)
void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri, int reg)
{
struct stream *s;
struct prefix *p;
@ -146,22 +140,16 @@ bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
stream_putw(s, flags); /* initial flags */
stream_putw(s, PREFIX_FAMILY(p));
stream_put_prefix(s, p);
if (reg)
{
if (reg) {
assert(ri);
if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
{
assert (ri->attr->extra);
if (ri->attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
{
if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX) {
flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
stream_putl (s, ri->attr->extra->label_index);
stream_putl(s, ri->attr->label_index);
}
}
SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
}
else
} else
UNSET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
/* Set length and flags */
@ -171,30 +159,40 @@ bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
zclient_send_message(zclient);
}
static int
bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen,
u_char label[])
static int bgp_nlri_get_labels(struct peer *peer, u_char *pnt, u_char plen,
mpls_label_t *label)
{
u_char *data = pnt;
u_char *lim = pnt + plen;
u_char llen = 0;
u_char label_depth = 0;
for (; data < lim; data += BGP_LABEL_BYTES)
{
for (; data < lim; data += BGP_LABEL_BYTES) {
memcpy(label, data, BGP_LABEL_BYTES);
llen += 3;
llen += BGP_LABEL_BYTES;
bgp_set_valid_label(label);
label_depth += 1;
if (bgp_is_withdraw_label(label) || label_bos(label))
break;
}
/* If we RX multiple labels we will end up keeping only the last
* one. We do not yet support a label stack greater than 1. */
if (label_depth > 1)
zlog_warn("%s rcvd UPDATE with label stack %d deep", peer->host,
label_depth);
if (!(bgp_is_withdraw_label(label) || label_bos(label)))
zlog_warn("%s: [Update:RCVD] invalid label - no bottom of stack",
zlog_warn(
"%s rcvd UPDATE with invalid label stack - no bottom of stack",
peer->host);
return llen;
}
int
bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
struct bgp_nlri *packet)
{
u_char *pnt;
@ -206,7 +204,7 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
safi_t safi;
int addpath_encoded;
u_int32_t addpath_id;
u_char label[3];
mpls_label_t label = MPLS_INVALID_LABEL;
u_char llen;
/* Check peer status. */
@ -219,17 +217,17 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
safi = packet->safi;
addpath_id = 0;
addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
addpath_encoded =
(CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
&& CHECK_FLAG(peer->af_cap[afi][safi],
PEER_CAP_ADDPATH_AF_TX_RCV));
for (; pnt < lim; pnt += psize)
{
for (; pnt < lim; pnt += psize) {
/* Clear prefix structure. */
memset(&p, 0, sizeof(struct prefix));
llen = 0;
if (addpath_encoded)
{
if (addpath_encoded) {
/* When packet overflow occurs return immediately. */
if (pnt + BGP_ADDPATH_ID_LEN > lim)
@ -245,23 +243,21 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
psize = PSIZE(prefixlen);
/* sanity check against packet data */
if ((pnt + psize) > lim)
{
zlog_err ("%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
peer->host,
prefixlen, (uint)(lim-pnt));
if ((pnt + psize) > lim) {
zlog_err(
"%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
peer->host, prefixlen, (uint)(lim - pnt));
return -1;
}
/* Fill in the labels */
llen = bgp_nlri_get_labels(peer, pnt, psize, label);
// zlog_debug("rcvd label [%x/%x/%x], llen=%d\n", label[0], label[1], label[2], llen);
llen = bgp_nlri_get_labels(peer, pnt, psize, &label);
p.prefixlen = prefixlen - BSIZE(llen);
/* There needs to be at least one label */
if (prefixlen < 24)
{
zlog_err ("%s [Error] Update packet error"
if (prefixlen < 24) {
zlog_err(
"%s [Error] Update packet error"
" (wrong label length %d)",
peer->host, prefixlen);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
@ -277,62 +273,66 @@ bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
memcpy(&p.u.prefix, pnt + llen, psize - llen);
/* Check address. */
if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
{
if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
{
if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST) {
if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
/* From RFC4271 Section 6.3:
*
* If a prefix in the NLRI field is semantically incorrect
* (e.g., an unexpected multicast IP address), an error SHOULD
* be logged locally, and the prefix SHOULD be ignored.
* If a prefix in the NLRI field is semantically
* incorrect
* (e.g., an unexpected multicast IP address),
* an error SHOULD
* be logged locally, and the prefix SHOULD be
* ignored.
*/
zlog_err ("%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
zlog_err(
"%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
peer->host, inet_ntoa(p.u.prefix4));
continue;
}
}
/* Check address. */
if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
{
if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
{
if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST) {
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
char buf[BUFSIZ];
zlog_err ("%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
zlog_err(
"%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
BUFSIZ));
continue;
}
if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
{
if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
char buf[BUFSIZ];
zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
zlog_err(
"%s: IPv6 unicast NLRI is multicast address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
BUFSIZ));
continue;
}
}
if (attr)
{
bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, 0, NULL);
}
else
{
bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, NULL);
if (attr) {
bgp_update(peer, &p, addpath_id, attr, packet->afi,
SAFI_UNICAST, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
} else {
bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
SAFI_UNICAST, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, NULL, &label, NULL);
}
}
/* Packet length consistency check. */
if (pnt != lim)
{
zlog_err ("%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
if (pnt != lim) {
zlog_err(
"%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
peer->host, lim - pnt);
return -1;
}

View File

@ -32,82 +32,80 @@ struct peer;
extern void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri,
int reg);
extern int bgp_parse_fec_update(void);
extern u_char * bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
struct peer *to, afi_t afi, safi_t safi);
extern int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
struct bgp_nlri *packet);
static inline int
bgp_labeled_safi (safi_t safi)
static inline int bgp_labeled_safi(safi_t safi)
{
if ((safi == SAFI_LABELED_UNICAST) || (safi == SAFI_MPLS_VPN) ||
(safi == SAFI_EVPN))
/* NOTE: This API really says a label (tag) MAY be present. Not all EVPN
* routes will have a label.
*/
if ((safi == SAFI_LABELED_UNICAST) || (safi == SAFI_MPLS_VPN)
|| (safi == SAFI_EVPN))
return 1;
return 0;
}
static inline int
bgp_is_withdraw_label (u_char *pkt)
static inline int bgp_is_withdraw_label(mpls_label_t *label)
{
if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && (pkt[2] == 0x00))
u_char *pkt = (u_char *)label;
/* The check on pkt[2] for 0x00 or 0x02 is in case bgp_set_valid_label()
* was called on the withdraw label */
if ((pkt[0] == 0x80) && (pkt[1] == 0x00)
&& ((pkt[2] == 0x00) || (pkt[2] == 0x02)))
return 1;
return 0;
}
static inline u_char *
bgp_encode_withdraw_label (u_char *pkt)
{
*pkt++ = 0x80; *pkt++ = 0x00; *pkt++ = 0x00;
return pkt;
}
static inline int
bgp_is_valid_label (u_char *t)
static inline int bgp_is_valid_label(mpls_label_t *label)
{
u_char *t = (u_char *)label;
if (!t)
return 0;
return (t[2] & 0x02);
}
static inline void
bgp_set_valid_label (u_char *t)
static inline void bgp_set_valid_label(mpls_label_t *label)
{
u_char *t = (u_char *)label;
if (t)
t[2] |= 0x02;
}
static inline void
bgp_unset_valid_label (u_char *t)
static inline void bgp_unset_valid_label(mpls_label_t *label)
{
u_char *t = (u_char *)label;
if (t)
t[2] &= ~0x02;
}
static inline void
bgp_register_for_label (struct bgp_node *rn, struct bgp_info *ri)
static inline void bgp_register_for_label(struct bgp_node *rn,
struct bgp_info *ri)
{
bgp_reg_dereg_for_label(rn, ri, 1);
}
static inline void
bgp_unregister_for_label (struct bgp_node *rn)
static inline void bgp_unregister_for_label(struct bgp_node *rn)
{
bgp_reg_dereg_for_label(rn, NULL, 0);
}
/* Label stream to value */
static inline u_int32_t
label_pton (u_char t[])
static inline u_int32_t label_pton(mpls_label_t *label)
{
return ((((unsigned int) t[0]) << 12) | (((unsigned int) t[1]) << 4) |
((unsigned int) ((t[2] & 0xF0) >> 4)));
u_char *t = (u_char *)label;
return ((((unsigned int)t[0]) << 12) | (((unsigned int)t[1]) << 4)
| ((unsigned int)((t[2] & 0xF0) >> 4)));
}
/* Encode label values */
static inline void
label_ntop (u_int32_t l, int bos, u_char t[])
static inline void label_ntop(u_int32_t l, int bos, mpls_label_t *label)
{
u_char *t = (u_char *)label;
t[0] = ((l & 0x000FF000) >> 12);
t[1] = ((l & 0x00000FF0) >> 4);
t[2] = ((l & 0x0000000F) << 4);
@ -116,9 +114,9 @@ label_ntop (u_int32_t l, int bos, u_char t[])
}
/* Return BOS value of label stream */
static inline u_char
label_bos (u_char t[])
static inline u_char label_bos(mpls_label_t *label)
{
u_char *t = (u_char *)label;
return (t[2] & 0x01);
};

View File

@ -34,16 +34,14 @@
static struct hash *lcomhash;
/* Allocate a new lcommunities. */
static struct lcommunity *
lcommunity_new (void)
static struct lcommunity *lcommunity_new(void)
{
return (struct lcommunity *)XCALLOC(MTYPE_LCOMMUNITY,
sizeof(struct lcommunity));
}
/* Allocate lcommunities. */
void
lcommunity_free (struct lcommunity **lcom)
void lcommunity_free(struct lcommunity **lcom)
{
if ((*lcom)->val)
XFREE(MTYPE_LCOMMUNITY_VAL, (*lcom)->val);
@ -53,8 +51,7 @@ lcommunity_free (struct lcommunity **lcom)
lcom = NULL;
}
static void
lcommunity_hash_free (struct lcommunity *lcom)
static void lcommunity_hash_free(struct lcommunity *lcom)
{
lcommunity_free(&lcom);
}
@ -64,16 +61,15 @@ lcommunity_hash_free (struct lcommunity *lcom)
structure, we don't add the value. Newly added value is sorted by
numerical order. When the value is added to the structure return 1
else return 0. */
static int
lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
static int lcommunity_add_val(struct lcommunity *lcom,
struct lcommunity_val *lval)
{
u_int8_t *p;
int ret;
int c;
/* When this is fist value, just add it. */
if (lcom->val == NULL)
{
if (lcom->val == NULL) {
lcom->size++;
lcom->val = XMALLOC(MTYPE_LCOMMUNITY_VAL, lcom_length(lcom));
memcpy(lcom->val, lval->val, LCOMMUNITY_SIZE);
@ -82,8 +78,7 @@ lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
/* If the value already exists in the structure return 0. */
c = 0;
for (p = lcom->val; c < lcom->size; p += LCOMMUNITY_SIZE, c++)
{
for (p = lcom->val; c < lcom->size; p += LCOMMUNITY_SIZE, c++) {
ret = memcmp(p, lval->val, LCOMMUNITY_SIZE);
if (ret == 0)
return 0;
@ -93,7 +88,8 @@ lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
/* Add the value to the structure with numerical sorting. */
lcom->size++;
lcom->val = XREALLOC (MTYPE_LCOMMUNITY_VAL, lcom->val, lcom_length (lcom));
lcom->val =
XREALLOC(MTYPE_LCOMMUNITY_VAL, lcom->val, lcom_length(lcom));
memmove(lcom->val + (c + 1) * LCOMMUNITY_SIZE,
lcom->val + c * LCOMMUNITY_SIZE,
@ -106,8 +102,7 @@ lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
/* This function takes pointer to Large Communites strucutre then
create a new Large Communities structure by uniq and sort each
Large Communities value. */
struct lcommunity *
lcommunity_uniq_sort (struct lcommunity *lcom)
struct lcommunity *lcommunity_uniq_sort(struct lcommunity *lcom)
{
int i;
struct lcommunity *new;
@ -118,17 +113,16 @@ lcommunity_uniq_sort (struct lcommunity *lcom)
new = lcommunity_new();
for (i = 0; i < lcom->size; i++)
{
lval = (struct lcommunity_val *) (lcom->val + (i * LCOMMUNITY_SIZE));
for (i = 0; i < lcom->size; i++) {
lval = (struct lcommunity_val *)(lcom->val
+ (i * LCOMMUNITY_SIZE));
lcommunity_add_val(new, lval);
}
return new;
}
/* Parse Large Communites Attribute in BGP packet. */
struct lcommunity *
lcommunity_parse (u_int8_t *pnt, u_short length)
struct lcommunity *lcommunity_parse(u_int8_t *pnt, u_short length)
{
struct lcommunity tmp;
struct lcommunity *new;
@ -150,53 +144,52 @@ lcommunity_parse (u_int8_t *pnt, u_short length)
}
/* Duplicate the Large Communities Attribute structure. */
struct lcommunity *
lcommunity_dup (struct lcommunity *lcom)
struct lcommunity *lcommunity_dup(struct lcommunity *lcom)
{
struct lcommunity *new;
new = XCALLOC(MTYPE_LCOMMUNITY, sizeof(struct lcommunity));
new->size = lcom->size;
if (new->size)
{
new->val = XMALLOC (MTYPE_LCOMMUNITY_VAL, lcom->size * LCOMMUNITY_SIZE);
if (new->size) {
new->val = XMALLOC(MTYPE_LCOMMUNITY_VAL,
lcom->size * LCOMMUNITY_SIZE);
memcpy(new->val, lcom->val, lcom->size * LCOMMUNITY_SIZE);
}
else
} else
new->val = NULL;
return new;
}
/* Retrun string representation of communities attribute. */
char *
lcommunity_str (struct lcommunity *lcom)
char *lcommunity_str(struct lcommunity *lcom)
{
if (!lcom->str)
lcom->str = lcommunity_lcom2str (lcom, LCOMMUNITY_FORMAT_DISPLAY);
lcom->str =
lcommunity_lcom2str(lcom, LCOMMUNITY_FORMAT_DISPLAY);
return lcom->str;
}
/* Merge two Large Communities Attribute structure. */
struct lcommunity *
lcommunity_merge (struct lcommunity *lcom1, struct lcommunity *lcom2)
struct lcommunity *lcommunity_merge(struct lcommunity *lcom1,
struct lcommunity *lcom2)
{
if (lcom1->val)
lcom1->val = XREALLOC (MTYPE_LCOMMUNITY_VAL, lcom1->val,
lcom1->val =
XREALLOC(MTYPE_LCOMMUNITY_VAL, lcom1->val,
(lcom1->size + lcom2->size) * LCOMMUNITY_SIZE);
else
lcom1->val = XMALLOC (MTYPE_LCOMMUNITY_VAL,
lcom1->val =
XMALLOC(MTYPE_LCOMMUNITY_VAL,
(lcom1->size + lcom2->size) * LCOMMUNITY_SIZE);
memcpy (lcom1->val + (lcom1->size * LCOMMUNITY_SIZE),
lcom2->val, lcom2->size * LCOMMUNITY_SIZE);
memcpy(lcom1->val + (lcom1->size * LCOMMUNITY_SIZE), lcom2->val,
lcom2->size * LCOMMUNITY_SIZE);
lcom1->size += lcom2->size;
return lcom1;
}
/* Intern Large Communities Attribute. */
struct lcommunity *
lcommunity_intern (struct lcommunity *lcom)
struct lcommunity *lcommunity_intern(struct lcommunity *lcom)
{
struct lcommunity *find;
@ -210,14 +203,14 @@ lcommunity_intern (struct lcommunity *lcom)
find->refcnt++;
if (!find->str)
find->str = lcommunity_lcom2str (find, LCOMMUNITY_FORMAT_DISPLAY);
find->str =
lcommunity_lcom2str(find, LCOMMUNITY_FORMAT_DISPLAY);
return find;
}
/* Unintern Large Communities Attribute. */
void
lcommunity_unintern (struct lcommunity **lcom)
void lcommunity_unintern(struct lcommunity **lcom)
{
struct lcommunity *ret;
@ -225,8 +218,7 @@ lcommunity_unintern (struct lcommunity **lcom)
(*lcom)->refcnt--;
/* Pull off from hash. */
if ((*lcom)->refcnt == 0)
{
if ((*lcom)->refcnt == 0) {
/* Large community must be in the hash. */
ret = (struct lcommunity *)hash_release(lcomhash, *lcom);
assert(ret != NULL);
@ -236,8 +228,7 @@ lcommunity_unintern (struct lcommunity **lcom)
}
/* Utility function to make hash key. */
unsigned int
lcommunity_hash_make (void *arg)
unsigned int lcommunity_hash_make(void *arg)
{
const struct lcommunity *lcom = arg;
int size = lcom->size * LCOMMUNITY_SIZE;
@ -245,8 +236,7 @@ lcommunity_hash_make (void *arg)
unsigned int key = 0;
int c;
for (c = 0; c < size; c += LCOMMUNITY_SIZE)
{
for (c = 0; c < size; c += LCOMMUNITY_SIZE) {
key += pnt[c];
key += pnt[c + 1];
key += pnt[c + 2];
@ -265,32 +255,29 @@ lcommunity_hash_make (void *arg)
}
/* Compare two Large Communities Attribute structure. */
int
lcommunity_cmp (const void *arg1, const void *arg2)
int lcommunity_cmp(const void *arg1, const void *arg2)
{
const struct lcommunity *lcom1 = arg1;
const struct lcommunity *lcom2 = arg2;
return (lcom1->size == lcom2->size
&& memcmp (lcom1->val, lcom2->val, lcom1->size * LCOMMUNITY_SIZE) == 0);
&& memcmp(lcom1->val, lcom2->val, lcom1->size * LCOMMUNITY_SIZE)
== 0);
}
/* Return communities hash. */
struct hash *
lcommunity_hash (void)
struct hash *lcommunity_hash(void)
{
return lcomhash;
}
/* Initialize Large Comminities related hash. */
void
lcommunity_init (void)
void lcommunity_init(void)
{
lcomhash = hash_create(lcommunity_hash_make, lcommunity_cmp, NULL);
}
void
lcommunity_finish (void)
void lcommunity_finish(void)
{
hash_clean(lcomhash, (void (*)(void *))lcommunity_hash_free);
hash_free(lcomhash);
@ -298,22 +285,20 @@ lcommunity_finish (void)
}
/* Large Communities token enum. */
enum lcommunity_token
{
enum lcommunity_token {
lcommunity_token_unknown = 0,
lcommunity_token_val,
};
/* Get next Large Communities token from the string. */
static const char *
lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
static const char *lcommunity_gettoken(const char *str,
struct lcommunity_val *lval,
enum lcommunity_token *token)
{
const char *p = str;
/* Skip white space. */
while (isspace ((int) *p))
{
while (isspace((int)*p)) {
p++;
str++;
}
@ -323,25 +308,19 @@ lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
return NULL;
/* Community value. */
if (isdigit ((int) *p))
{
if (isdigit((int)*p)) {
int separator = 0;
int digit = 0;
u_int32_t globaladmin = 0;
u_int32_t localdata1 = 0;
u_int32_t localdata2 = 0;
while (isdigit ((int) *p) || *p == ':')
{
if (*p == ':')
{
if (separator == 2)
{
while (isdigit((int)*p) || *p == ':') {
if (*p == ':') {
if (separator == 2) {
*token = lcommunity_token_unknown;
return NULL;
}
else
{
} else {
separator++;
digit = 0;
if (separator == 1) {
@ -351,17 +330,14 @@ lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
}
localdata2 = 0;
}
}
else
{
} else {
digit = 1;
localdata2 *= 10;
localdata2 += (*p - '0');
}
p++;
}
if (! digit)
{
if (!digit) {
*token = lcommunity_token_unknown;
return NULL;
}
@ -396,17 +372,14 @@ lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
When string includes keyword for each large community value.
Please specify keyword_included as non-zero value.
*/
struct lcommunity *
lcommunity_str2com (const char *str)
struct lcommunity *lcommunity_str2com(const char *str)
{
struct lcommunity *lcom = NULL;
enum lcommunity_token token = lcommunity_token_unknown;
struct lcommunity_val lval;
while ((str = lcommunity_gettoken (str, &lval, &token)))
{
switch (token)
{
while ((str = lcommunity_gettoken(str, &lval, &token))) {
switch (token) {
case lcommunity_token_val:
if (lcom == NULL)
lcom = lcommunity_new();
@ -422,8 +395,7 @@ lcommunity_str2com (const char *str)
return lcom;
}
int
lcommunity_include (struct lcommunity *lcom, u_char *ptr)
int lcommunity_include(struct lcommunity *lcom, u_char *ptr)
{
int i;
u_char *lcom_ptr;
@ -440,8 +412,7 @@ lcommunity_include (struct lcommunity *lcom, u_char *ptr)
/* Convert large community attribute to string.
The large coms will be in 65535:65531:0 format.
*/
char *
lcommunity_lcom2str (struct lcommunity *lcom, int format)
char *lcommunity_lcom2str(struct lcommunity *lcom, int format)
{
int i;
u_int8_t *pnt;
@ -453,8 +424,7 @@ lcommunity_lcom2str (struct lcommunity *lcom, int format)
int first = 1;
u_int32_t globaladmin, localdata1, localdata2;
if (lcom->size == 0)
{
if (lcom->size == 0) {
str_buf = XMALLOC(MTYPE_LCOMMUNITY_STR, 1);
str_buf[0] = '\0';
return str_buf;
@ -465,13 +435,12 @@ lcommunity_lcom2str (struct lcommunity *lcom, int format)
str_size = LCOMMUNITY_STR_DEFAULT_LEN + 1;
str_pnt = 0;
for (i = 0; i < lcom->size; i++)
{
for (i = 0; i < lcom->size; i++) {
/* Make it sure size is enough. */
while (str_pnt + LCOMMUNITY_STR_DEFAULT_LEN >= str_size)
{
while (str_pnt + LCOMMUNITY_STR_DEFAULT_LEN >= str_size) {
str_size *= 2;
str_buf = XREALLOC (MTYPE_LCOMMUNITY_STR, str_buf, str_size);
str_buf = XREALLOC(MTYPE_LCOMMUNITY_STR, str_buf,
str_size);
}
/* Space between each value. */
@ -503,8 +472,7 @@ lcommunity_lcom2str (struct lcommunity *lcom, int format)
return str_buf;
}
int
lcommunity_match (const struct lcommunity *lcom1,
int lcommunity_match(const struct lcommunity *lcom1,
const struct lcommunity *lcom2)
{
int i = 0;
@ -520,9 +488,10 @@ lcommunity_match (const struct lcommunity *lcom1,
return 0;
/* Every community on com2 needs to be on com1 for this to match */
while (i < lcom1->size && j < lcom2->size)
{
if (memcmp (lcom1->val + (i*12), lcom2->val + (j*12), LCOMMUNITY_SIZE) == 0)
while (i < lcom1->size && j < lcom2->size) {
if (memcmp(lcom1->val + (i * 12), lcom2->val + (j * 12),
LCOMMUNITY_SIZE)
== 0)
j++;
i++;
}
@ -534,8 +503,7 @@ lcommunity_match (const struct lcommunity *lcom1,
}
/* Delete one lcommunity. */
void
lcommunity_del_val (struct lcommunity *lcom, u_char *ptr)
void lcommunity_del_val(struct lcommunity *lcom, u_char *ptr)
{
int i = 0;
int c = 0;
@ -543,22 +511,24 @@ lcommunity_del_val (struct lcommunity *lcom, u_char *ptr)
if (!lcom->val)
return;
while (i < lcom->size)
{
if (memcmp (lcom->val + i*LCOMMUNITY_SIZE, ptr, LCOMMUNITY_SIZE) == 0)
{
while (i < lcom->size) {
if (memcmp(lcom->val + i * LCOMMUNITY_SIZE, ptr,
LCOMMUNITY_SIZE)
== 0) {
c = lcom->size - i - 1;
if (c > 0)
memmove (lcom->val + i*LCOMMUNITY_SIZE, lcom->val + (i + 1)*LCOMMUNITY_SIZE, c * LCOMMUNITY_SIZE);
memmove(lcom->val + i * LCOMMUNITY_SIZE,
lcom->val + (i + 1) * LCOMMUNITY_SIZE,
c * LCOMMUNITY_SIZE);
lcom->size--;
if (lcom->size > 0)
lcom->val = XREALLOC (MTYPE_COMMUNITY_VAL, lcom->val,
lcom->val =
XREALLOC(MTYPE_COMMUNITY_VAL, lcom->val,
lcom_length(lcom));
else
{
else {
XFREE(MTYPE_COMMUNITY_VAL, lcom->val);
lcom->val = NULL;
}

View File

@ -30,8 +30,7 @@
#define LCOMMUNITY_SIZE 12
/* Large Communities attribute. */
struct lcommunity
{
struct lcommunity {
/* Reference counter. */
unsigned long refcnt;
@ -46,8 +45,7 @@ struct lcommunity
};
/* Extended community value is eight octet. */
struct lcommunity_val
{
struct lcommunity_val {
char val[LCOMMUNITY_SIZE];
};
@ -58,7 +56,8 @@ extern void lcommunity_finish (void);
extern void lcommunity_free(struct lcommunity **);
extern struct lcommunity *lcommunity_parse(u_int8_t *, u_short);
extern struct lcommunity *lcommunity_dup(struct lcommunity *);
extern struct lcommunity *lcommunity_merge (struct lcommunity *, struct lcommunity *);
extern struct lcommunity *lcommunity_merge(struct lcommunity *,
struct lcommunity *);
extern struct lcommunity *lcommunity_uniq_sort(struct lcommunity *);
extern struct lcommunity *lcommunity_intern(struct lcommunity *);
extern int lcommunity_cmp(const void *, const void *);
@ -67,7 +66,8 @@ extern unsigned int lcommunity_hash_make (void *);
extern struct hash *lcommunity_hash(void);
extern struct lcommunity *lcommunity_str2com(const char *);
extern char *lcommunity_lcom2str(struct lcommunity *, int);
extern int lcommunity_match (const struct lcommunity *, const struct lcommunity *);
extern int lcommunity_match(const struct lcommunity *,
const struct lcommunity *);
extern char *lcommunity_str(struct lcommunity *);
extern int lcommunity_include(struct lcommunity *lcom, u_char *ptr);
extern void lcommunity_del_val(struct lcommunity *lcom, u_char *ptr);

View File

@ -60,16 +60,14 @@
#endif
/* bgpd options, we use GNU getopt library. */
static const struct option longopts[] =
{
static const struct option longopts[] = {
{"bgp_port", required_argument, NULL, 'p'},
{"listenon", required_argument, NULL, 'l'},
{"retain", no_argument, NULL, 'r'},
{"no_kernel", no_argument, NULL, 'n'},
{"skip_runas", no_argument, NULL, 'S'},
{"ecmp", required_argument, NULL, 'e'},
{ 0 }
};
{0}};
/* signal definitions */
void sighup(void);
@ -79,8 +77,7 @@ void sigusr1 (void);
static void bgp_exit(int);
static void bgp_vrf_terminate(void);
static struct quagga_signal_t bgp_signals[] =
{
static struct quagga_signal_t bgp_signals[] = {
{
.signal = SIGHUP,
.handler = &sighup,
@ -103,15 +100,11 @@ static struct quagga_signal_t bgp_signals[] =
static int retain_mode = 0;
/* privileges */
static zebra_capabilities_t _caps_p [] =
{
ZCAP_BIND,
ZCAP_NET_RAW,
ZCAP_NET_ADMIN,
static zebra_capabilities_t _caps_p[] = {
ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN,
};
struct zebra_privs_t bgpd_privs =
{
struct zebra_privs_t bgpd_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP)
.user = FRR_USER,
.group = FRR_GROUP,
@ -127,8 +120,7 @@ struct zebra_privs_t bgpd_privs =
static struct frr_daemon_info bgpd_di;
/* SIGHUP handler. */
void
sighup (void)
void sighup(void)
{
zlog_info("SIGHUP received");
@ -144,13 +136,11 @@ sighup (void)
}
/* SIGINT handler. */
__attribute__((__noreturn__)) void
sigint (void)
__attribute__((__noreturn__)) void sigint(void)
{
zlog_notice("Terminating on signal");
if (! retain_mode)
{
if (!retain_mode) {
bgp_terminate();
if (bgpd_privs.user) /* NULL if skip_runas flag set */
zprivs_terminate(&bgpd_privs);
@ -162,8 +152,7 @@ sigint (void)
}
/* SIGUSR1 handler. */
void
sigusr1 (void)
void sigusr1(void)
{
zlog_rotate();
}
@ -175,8 +164,7 @@ sigusr1 (void)
Zebra route removal and protocol teardown are not meant to be done here.
For example, "retain_mode" may be set.
*/
static __attribute__((__noreturn__)) void
bgp_exit (int status)
static __attribute__((__noreturn__)) void bgp_exit(int status)
{
struct bgp *bgp;
struct listnode *node, *nnode;
@ -232,12 +220,6 @@ bgp_exit (int status)
vnc_zebra_destroy();
#endif
bgp_zebra_destroy();
if (bgp_nexthop_buf)
stream_free (bgp_nexthop_buf);
if (bgp_ifindices_buf)
stream_free (bgp_ifindices_buf);
if (bgp_label_buf)
stream_free (bgp_label_buf);
/* reverse bgp_master_init */
if (bm->master)
@ -253,8 +235,7 @@ bgp_exit (int status)
exit(status);
}
static int
bgp_vrf_new (struct vrf *vrf)
static int bgp_vrf_new(struct vrf *vrf)
{
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
@ -262,8 +243,7 @@ bgp_vrf_new (struct vrf *vrf)
return 0;
}
static int
bgp_vrf_delete (struct vrf *vrf)
static int bgp_vrf_delete(struct vrf *vrf)
{
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
@ -271,8 +251,7 @@ bgp_vrf_delete (struct vrf *vrf)
return 0;
}
static int
bgp_vrf_enable (struct vrf *vrf)
static int bgp_vrf_enable(struct vrf *vrf)
{
struct bgp *bgp;
vrf_id_t old_vrf_id;
@ -281,8 +260,7 @@ bgp_vrf_enable (struct vrf *vrf)
zlog_debug("VRF enable add %s id %d", vrf->name, vrf->vrf_id);
bgp = bgp_lookup_by_name(vrf->name);
if (bgp)
{
if (bgp) {
old_vrf_id = bgp->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
bgp_vrf_link(bgp, vrf);
@ -296,8 +274,7 @@ bgp_vrf_enable (struct vrf *vrf)
return 0;
}
static int
bgp_vrf_disable (struct vrf *vrf)
static int bgp_vrf_disable(struct vrf *vrf)
{
struct bgp *bgp;
vrf_id_t old_vrf_id;
@ -309,10 +286,10 @@ bgp_vrf_disable (struct vrf *vrf)
zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
bgp = bgp_lookup_by_name(vrf->name);
if (bgp)
{
if (bgp) {
old_vrf_id = bgp->vrf_id;
/* We have instance configured, unlink from VRF and make it "down". */
/* We have instance configured, unlink from VRF and make it
* "down". */
bgp_vrf_unlink(bgp, vrf);
/* Update any redistribute vrf bitmaps if the vrf_id changed */
if (old_vrf_id != bgp->vrf_id)
@ -324,36 +301,27 @@ bgp_vrf_disable (struct vrf *vrf)
return 0;
}
static void
bgp_vrf_init (void)
static void bgp_vrf_init(void)
{
vrf_init (bgp_vrf_new,
bgp_vrf_enable,
bgp_vrf_disable,
bgp_vrf_delete);
vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable, bgp_vrf_delete);
}
static void
bgp_vrf_terminate (void)
static void bgp_vrf_terminate(void)
{
vrf_terminate();
}
FRR_DAEMON_INFO(bgpd, BGP,
.vty_port = BGP_VTY_PORT,
FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
.proghelp = "Implementation of the BGP routing protocol.",
.signals = bgp_signals,
.n_signals = array_size(bgp_signals),
.signals = bgp_signals, .n_signals = array_size(bgp_signals),
.privs = &bgpd_privs,
)
.privs = &bgpd_privs, )
/* Main routine of bgpd. Treatment of argument and start bgp finite
state machine is handled at here. */
int
main (int argc, char **argv)
int main(int argc, char **argv)
{
int opt;
int tmp_port;
@ -364,7 +332,8 @@ main (int argc, char **argv)
int skip_runas = 0;
frr_preinit(&bgpd_di, argc, argv);
frr_opt_add("p:l:rne:", longopts,
frr_opt_add(
"p:l:rne:", longopts,
" -p, --bgp_port Set bgp protocol's port number\n"
" -l, --listenon Listen on specified address (implies -n)\n"
" -r, --retain When program terminates, retain added route by bgpd.\n"
@ -373,15 +342,13 @@ main (int argc, char **argv)
" -e, --ecmp Specify ECMP to use.\n");
/* Command line argument treatment. */
while (1)
{
while (1) {
opt = frr_getopt(argc, argv, 0);
if (opt == EOF)
break;
switch (opt)
{
switch (opt) {
case 0:
break;
case 'p':
@ -393,9 +360,11 @@ main (int argc, char **argv)
break;
case 'e':
multipath_num = atoi(optarg);
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
{
zlog_err ("Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM);
if (multipath_num > MULTIPATH_NUM
|| multipath_num <= 0) {
zlog_err(
"Multipath Number specified must be less than %d and greater than 0",
MULTIPATH_NUM);
return 1;
}
break;
@ -405,6 +374,7 @@ main (int argc, char **argv)
case 'l':
bgp_address = optarg;
/* listenon implies -n */
/* fallthru */
case 'n':
no_fib_flag = 1;
break;
@ -433,8 +403,7 @@ main (int argc, char **argv)
bgp_init();
snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), ", bgp@%s:%d",
(bm->address ? bm->address : "<all>"),
bm->port);
(bm->address ? bm->address : "<all>"), bm->port);
frr_config_fork();
frr_run(bm->master);

View File

@ -43,7 +43,6 @@ DEFINE_MTYPE(BGPD, BGP_UPDGRP, "BGP update group")
DEFINE_MTYPE(BGPD, BGP_UPD_SUBGRP, "BGP update subgroup")
DEFINE_MTYPE(BGPD, BGP_PACKET, "BGP packet")
DEFINE_MTYPE(BGPD, ATTR, "BGP attribute")
DEFINE_MTYPE(BGPD, ATTR_EXTRA, "BGP extra attributes")
DEFINE_MTYPE(BGPD, AS_PATH, "BGP aspath")
DEFINE_MTYPE(BGPD, AS_SEG, "BGP aspath seg")
DEFINE_MTYPE(BGPD, AS_SEG_DATA, "BGP aspath segment data")
@ -114,3 +113,7 @@ DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value")
DEFINE_MTYPE(BGPD, LCOMMUNITY, "Large Community")
DEFINE_MTYPE(BGPD, LCOMMUNITY_STR, "Large Community display string")
DEFINE_MTYPE(BGPD, LCOMMUNITY_VAL, "Large Community value")
DEFINE_MTYPE(BGPD, BGP_EVPN, "BGP EVPN Information")
DEFINE_MTYPE(BGPD, BGP_EVPN_IMPORT_RT, "BGP EVPN Import RT")
DEFINE_MTYPE(BGPD, BGP_EVPN_MACIP, "BGP EVPN MAC IP")

View File

@ -39,7 +39,6 @@ DECLARE_MTYPE(BGP_UPDGRP)
DECLARE_MTYPE(BGP_UPD_SUBGRP)
DECLARE_MTYPE(BGP_PACKET)
DECLARE_MTYPE(ATTR)
DECLARE_MTYPE(ATTR_EXTRA)
DECLARE_MTYPE(AS_PATH)
DECLARE_MTYPE(AS_SEG)
DECLARE_MTYPE(AS_SEG_DATA)
@ -110,4 +109,8 @@ DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE)
DECLARE_MTYPE(LCOMMUNITY)
DECLARE_MTYPE(LCOMMUNITY_STR)
DECLARE_MTYPE(LCOMMUNITY_VAL)
DECLARE_MTYPE(BGP_EVPN)
DECLARE_MTYPE(BGP_EVPN_IMPORT_RT)
DECLARE_MTYPE(BGP_EVPN_MACIP)
#endif /* _QUAGGA_BGP_MEMORY_H */

View File

@ -45,15 +45,13 @@
*
* Record maximum-paths configuration for BGP instance
*/
int
bgp_maximum_paths_set (struct bgp *bgp, afi_t afi, safi_t safi,
int peertype, u_int16_t maxpaths, u_int16_t options)
int bgp_maximum_paths_set(struct bgp *bgp, afi_t afi, safi_t safi, int peertype,
u_int16_t maxpaths, u_int16_t options)
{
if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
return -1;
switch (peertype)
{
switch (peertype) {
case BGP_PEER_IBGP:
bgp->maxpaths[afi][safi].maxpaths_ibgp = maxpaths;
bgp->maxpaths[afi][safi].ibgp_flags |= options;
@ -73,15 +71,13 @@ bgp_maximum_paths_set (struct bgp *bgp, afi_t afi, safi_t safi,
*
* Remove maximum-paths configuration from BGP instance
*/
int
bgp_maximum_paths_unset (struct bgp *bgp, afi_t afi, safi_t safi,
int bgp_maximum_paths_unset(struct bgp *bgp, afi_t afi, safi_t safi,
int peertype)
{
if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
return -1;
switch (peertype)
{
switch (peertype) {
case BGP_PEER_IBGP:
bgp->maxpaths[afi][safi].maxpaths_ibgp = multipath_num;
bgp->maxpaths[afi][safi].ibgp_flags = 0;
@ -103,53 +99,50 @@ bgp_maximum_paths_unset (struct bgp *bgp, afi_t afi, safi_t safi,
* or greater than zero if bi1 is respectively less than, equal to,
* or greater than bi2.
*/
int
bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2)
int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
{
struct attr_extra *ae1, *ae2;
int compare;
ae1 = bi1->attr->extra;
ae2 = bi2->attr->extra;
compare = IPV4_ADDR_CMP(&bi1->attr->nexthop, &bi2->attr->nexthop);
if (!compare && ae1 && ae2)
{
if (ae1->mp_nexthop_len == ae2->mp_nexthop_len)
{
switch (ae1->mp_nexthop_len)
{
if (!compare) {
if (bi1->attr->mp_nexthop_len == bi2->attr->mp_nexthop_len) {
switch (bi1->attr->mp_nexthop_len) {
case BGP_ATTR_NHLEN_IPV4:
case BGP_ATTR_NHLEN_VPNV4:
compare = IPV4_ADDR_CMP (&ae1->mp_nexthop_global_in,
&ae2->mp_nexthop_global_in);
compare = IPV4_ADDR_CMP(
&bi1->attr->mp_nexthop_global_in,
&bi2->attr->mp_nexthop_global_in);
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
&ae2->mp_nexthop_global);
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_global,
&bi2->attr->mp_nexthop_global);
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
&ae2->mp_nexthop_global);
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_global,
&bi2->attr->mp_nexthop_global);
if (!compare)
compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_local,
&ae2->mp_nexthop_local);
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_local,
&bi2->attr->mp_nexthop_local);
break;
}
}
/* This can happen if one IPv6 peer sends you global and link-local
/* This can happen if one IPv6 peer sends you global and
* link-local
* nexthops but another IPv6 peer only sends you global
*/
else if (ae1->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL ||
ae1->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
{
compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
&ae2->mp_nexthop_global);
if (!compare)
{
if (ae1->mp_nexthop_len < ae2->mp_nexthop_len)
else if (bi1->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
|| bi1->attr->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
compare = IPV6_ADDR_CMP(&bi1->attr->mp_nexthop_global,
&bi2->attr->mp_nexthop_global);
if (!compare) {
if (bi1->attr->mp_nexthop_len
< bi2->attr->mp_nexthop_len)
compare = -1;
else
compare = 1;
@ -172,8 +165,7 @@ bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2)
* The order of paths is determined first by received nexthop, and then
* by peer address if the nexthops are the same.
*/
static int
bgp_info_mpath_cmp (void *val1, void *val2)
static int bgp_info_mpath_cmp(void *val1, void *val2)
{
struct bgp_info *bi1, *bi2;
int compare;
@ -183,8 +175,7 @@ bgp_info_mpath_cmp (void *val1, void *val2)
compare = bgp_info_nexthop_cmp(bi1, bi2);
if (!compare)
{
if (!compare) {
if (!bi1->peer->su_remote && !bi2->peer->su_remote)
compare = 0;
else if (!bi1->peer->su_remote)
@ -192,7 +183,8 @@ bgp_info_mpath_cmp (void *val1, void *val2)
else if (!bi2->peer->su_remote)
compare = -1;
else
compare = sockunion_cmp (bi1->peer->su_remote, bi2->peer->su_remote);
compare = sockunion_cmp(bi1->peer->su_remote,
bi2->peer->su_remote);
}
return compare;
@ -204,8 +196,7 @@ bgp_info_mpath_cmp (void *val1, void *val2)
* Initialize the mp_list, which holds the list of multipaths
* selected by bgp_best_selection
*/
void
bgp_mp_list_init (struct list *mp_list)
void bgp_mp_list_init(struct list *mp_list)
{
assert(mp_list);
memset(mp_list, 0, sizeof(struct list));
@ -217,8 +208,7 @@ bgp_mp_list_init (struct list *mp_list)
*
* Clears all entries out of the mp_list
*/
void
bgp_mp_list_clear (struct list *mp_list)
void bgp_mp_list_clear(struct list *mp_list)
{
assert(mp_list);
list_delete_all_node(mp_list);
@ -229,8 +219,7 @@ bgp_mp_list_clear (struct list *mp_list)
*
* Adds a multipath entry to the mp_list
*/
void
bgp_mp_list_add (struct list *mp_list, struct bgp_info *mpinfo)
void bgp_mp_list_add(struct list *mp_list, struct bgp_info *mpinfo)
{
assert(mp_list && mpinfo);
listnode_add_sort(mp_list, mpinfo);
@ -241,11 +230,11 @@ bgp_mp_list_add (struct list *mp_list, struct bgp_info *mpinfo)
*
* Allocate and zero memory for a new bgp_info_mpath element
*/
static struct bgp_info_mpath *
bgp_info_mpath_new (void)
static struct bgp_info_mpath *bgp_info_mpath_new(void)
{
struct bgp_info_mpath *new_mpath;
new_mpath = XCALLOC (MTYPE_BGP_MPATH_INFO, sizeof (struct bgp_info_mpath));
new_mpath =
XCALLOC(MTYPE_BGP_MPATH_INFO, sizeof(struct bgp_info_mpath));
return new_mpath;
}
@ -254,11 +243,9 @@ bgp_info_mpath_new (void)
*
* Release resources for a bgp_info_mpath element and zero out pointer
*/
void
bgp_info_mpath_free (struct bgp_info_mpath **mpath)
{
if (mpath && *mpath)
void bgp_info_mpath_free(struct bgp_info_mpath **mpath)
{
if (mpath && *mpath) {
if ((*mpath)->mp_attr)
bgp_attr_unintern(&(*mpath)->mp_attr);
XFREE(MTYPE_BGP_MPATH_INFO, *mpath);
@ -272,12 +259,10 @@ bgp_info_mpath_free (struct bgp_info_mpath **mpath)
* Fetch the mpath element for the given bgp_info. Used for
* doing lazy allocation.
*/
static struct bgp_info_mpath *
bgp_info_mpath_get (struct bgp_info *binfo)
static struct bgp_info_mpath *bgp_info_mpath_get(struct bgp_info *binfo)
{
struct bgp_info_mpath *mpath;
if (!binfo->mpath)
{
if (!binfo->mpath) {
mpath = bgp_info_mpath_new();
if (!mpath)
return NULL;
@ -293,8 +278,8 @@ bgp_info_mpath_get (struct bgp_info *binfo)
* Enqueue a path onto the multipath list given the previous multipath
* list entry
*/
static void
bgp_info_mpath_enqueue (struct bgp_info *prev_info, struct bgp_info *binfo)
static void bgp_info_mpath_enqueue(struct bgp_info *prev_info,
struct bgp_info *binfo)
{
struct bgp_info_mpath *prev, *mpath;
@ -317,8 +302,7 @@ bgp_info_mpath_enqueue (struct bgp_info *prev_info, struct bgp_info *binfo)
*
* Remove a path from the multipath list
*/
void
bgp_info_mpath_dequeue (struct bgp_info *binfo)
void bgp_info_mpath_dequeue(struct bgp_info *binfo)
{
struct bgp_info_mpath *mpath = binfo->mpath;
if (!mpath)
@ -336,8 +320,7 @@ bgp_info_mpath_dequeue (struct bgp_info *binfo)
*
* Given a bgp_info, return the next multipath entry
*/
struct bgp_info *
bgp_info_mpath_next (struct bgp_info *binfo)
struct bgp_info *bgp_info_mpath_next(struct bgp_info *binfo)
{
if (!binfo->mpath || !binfo->mpath->mp_next)
return NULL;
@ -349,8 +332,7 @@ bgp_info_mpath_next (struct bgp_info *binfo)
*
* Given bestpath bgp_info, return the first multipath entry.
*/
struct bgp_info *
bgp_info_mpath_first (struct bgp_info *binfo)
struct bgp_info *bgp_info_mpath_first(struct bgp_info *binfo)
{
return bgp_info_mpath_next(binfo);
}
@ -360,8 +342,7 @@ bgp_info_mpath_first (struct bgp_info *binfo)
*
* Given the bestpath bgp_info, return the number of multipath entries
*/
u_int32_t
bgp_info_mpath_count (struct bgp_info *binfo)
u_int32_t bgp_info_mpath_count(struct bgp_info *binfo)
{
if (!binfo->mpath)
return 0;
@ -373,8 +354,7 @@ bgp_info_mpath_count (struct bgp_info *binfo)
*
* Sets the count of multipaths into bestpath's mpath element
*/
static void
bgp_info_mpath_count_set (struct bgp_info *binfo, u_int32_t count)
static void bgp_info_mpath_count_set(struct bgp_info *binfo, u_int32_t count)
{
struct bgp_info_mpath *mpath;
if (!count && !binfo->mpath)
@ -391,8 +371,7 @@ bgp_info_mpath_count_set (struct bgp_info *binfo, u_int32_t count)
* Given bestpath bgp_info, return aggregated attribute set used
* for advertising the multipath route
*/
struct attr *
bgp_info_mpath_attr (struct bgp_info *binfo)
struct attr *bgp_info_mpath_attr(struct bgp_info *binfo)
{
if (!binfo->mpath)
return NULL;
@ -404,8 +383,7 @@ bgp_info_mpath_attr (struct bgp_info *binfo)
*
* Sets the aggregated attribute into bestpath's mpath element
*/
static void
bgp_info_mpath_attr_set (struct bgp_info *binfo, struct attr *attr)
static void bgp_info_mpath_attr_set(struct bgp_info *binfo, struct attr *attr)
{
struct bgp_info_mpath *mpath;
if (!attr && !binfo->mpath)
@ -422,8 +400,7 @@ bgp_info_mpath_attr_set (struct bgp_info *binfo, struct attr *attr)
* Compare and sync up the multipath list with the mp_list generated by
* bgp_best_selection
*/
void
bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
void bgp_info_mpath_update(struct bgp_node *rn, struct bgp_info *new_best,
struct bgp_info *old_best, struct list *mp_list,
struct bgp_maxpaths_cfg *mpath_cfg)
{
@ -446,17 +423,16 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
if (debug)
prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
if (new_best)
{
if (new_best) {
mpath_count++;
if (new_best != old_best)
bgp_info_mpath_dequeue(new_best);
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP) ?
mpath_cfg->maxpaths_ibgp : mpath_cfg->maxpaths_ebgp;
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP)
? mpath_cfg->maxpaths_ibgp
: mpath_cfg->maxpaths_ebgp;
}
if (old_best)
{
if (old_best) {
cur_mpath = bgp_info_mpath_first(old_best);
old_mpath_count = bgp_info_mpath_count(old_best);
bgp_info_mpath_count_set(old_best, 0);
@ -464,7 +440,8 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
}
if (debug)
zlog_debug("%s: starting mpath update, newbest %s num candidates %d old-mpath-count %d",
zlog_debug(
"%s: starting mpath update, newbest %s num candidates %d old-mpath-count %d",
pfx_buf, new_best ? new_best->peer->host : "NONE",
listcount(mp_list), old_mpath_count);
@ -479,8 +456,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
* Note that new_best might be somewhere in the mp_list, so we need
* to skip over it
*/
while (mp_node || cur_mpath)
{
while (mp_node || cur_mpath) {
struct bgp_info *tmp_info;
/*
@ -496,41 +472,44 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
tmp_info = mp_node ? listgetdata(mp_node) : NULL;
if (debug)
zlog_debug("%s: comparing candidate %s with existing mpath %s",
pfx_buf, tmp_info ? tmp_info->peer->host : "NONE",
zlog_debug(
"%s: comparing candidate %s with existing mpath %s",
pfx_buf,
tmp_info ? tmp_info->peer->host : "NONE",
cur_mpath ? cur_mpath->peer->host : "NONE");
/*
* If equal, the path was a multipath and is still a multipath.
* Insert onto new multipath list if maxpaths allows.
*/
if (mp_node && (listgetdata (mp_node) == cur_mpath))
{
if (mp_node && (listgetdata(mp_node) == cur_mpath)) {
list_delete_node(mp_list, mp_node);
bgp_info_mpath_dequeue(cur_mpath);
if ((mpath_count < maxpaths) &&
bgp_info_nexthop_cmp (prev_mpath, cur_mpath))
{
if ((mpath_count < maxpaths)
&& bgp_info_nexthop_cmp(prev_mpath, cur_mpath)) {
bgp_info_mpath_enqueue(prev_mpath, cur_mpath);
prev_mpath = cur_mpath;
mpath_count++;
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug("%s: %s is still multipath, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(
cur_mpath, path_buf);
zlog_debug(
"%s: %s is still multipath, cur count %d",
pfx_buf, path_buf, mpath_count);
}
}
else
{
} else {
mpath_changed = 1;
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug ("%s: remove mpath %s nexthop %s, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(
cur_mpath, path_buf);
zlog_debug(
"%s: remove mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &cur_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
inet_ntop(AF_INET,
&cur_mpath->attr
->nexthop,
nh_buf[0],
sizeof(nh_buf[0])),
mpath_count);
}
}
@ -539,47 +518,54 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
continue;
}
if (cur_mpath && (!mp_node ||
(bgp_info_mpath_cmp (cur_mpath,
listgetdata (mp_node)) < 0)))
{
if (cur_mpath
&& (!mp_node
|| (bgp_info_mpath_cmp(cur_mpath, listgetdata(mp_node))
< 0))) {
/*
* If here, we have an old multipath and either the mp_list
* If here, we have an old multipath and either the
* mp_list
* is finished or the next mp_node points to a later
* multipath, so we need to purge this path from the
* multipath list
*/
bgp_info_mpath_dequeue(cur_mpath);
mpath_changed = 1;
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug ("%s: remove mpath %s nexthop %s, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(cur_mpath,
path_buf);
zlog_debug(
"%s: remove mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &cur_mpath->attr->nexthop,
inet_ntop(AF_INET,
&cur_mpath->attr->nexthop,
nh_buf[0], sizeof(nh_buf[0])),
mpath_count);
}
cur_mpath = next_mpath;
}
else
{
} else {
/*
* If here, we have a path on the mp_list that was not previously
* a multipath (due to non-equivalance or maxpaths exceeded),
* or the matching multipath is sorted later in the multipath
* list. Before we enqueue the path on the new multipath list,
* make sure its not on the old_best multipath list or referenced
* If here, we have a path on the mp_list that was not
* previously
* a multipath (due to non-equivalance or maxpaths
* exceeded),
* or the matching multipath is sorted later in the
* multipath
* list. Before we enqueue the path on the new multipath
* list,
* make sure its not on the old_best multipath list or
* referenced
* via next_mpath:
* - If next_mpath points to this new path, update next_mpath to
* - If next_mpath points to this new path, update
* next_mpath to
* point to the multipath after this one
* - Dequeue the path from the multipath list just to make sure
* - Dequeue the path from the multipath list just to
* make sure
*/
new_mpath = listgetdata(mp_node);
list_delete_node(mp_list, mp_node);
if ((mpath_count < maxpaths) && (new_mpath != new_best) &&
bgp_info_nexthop_cmp (prev_mpath, new_mpath))
{
if ((mpath_count < maxpaths) && (new_mpath != new_best)
&& bgp_info_nexthop_cmp(prev_mpath, new_mpath)) {
if (new_mpath == next_mpath)
bgp_info_mpath_next(new_mpath);
bgp_info_mpath_dequeue(new_mpath);
@ -588,13 +574,17 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
prev_mpath = new_mpath;
mpath_changed = 1;
mpath_count++;
if (debug)
{
bgp_info_path_with_addpath_rx_str(new_mpath, path_buf);
zlog_debug ("%s: add mpath %s nexthop %s, cur count %d",
if (debug) {
bgp_info_path_with_addpath_rx_str(
new_mpath, path_buf);
zlog_debug(
"%s: add mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &new_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
inet_ntop(AF_INET,
&new_mpath->attr
->nexthop,
nh_buf[0],
sizeof(nh_buf[0])),
mpath_count);
}
}
@ -602,14 +592,16 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
}
}
if (new_best)
{
if (new_best) {
if (debug)
zlog_debug("%s: New mpath count (incl newbest) %d mpath-change %s",
pfx_buf, mpath_count, mpath_changed ? "YES" : "NO");
zlog_debug(
"%s: New mpath count (incl newbest) %d mpath-change %s",
pfx_buf, mpath_count,
mpath_changed ? "YES" : "NO");
bgp_info_mpath_count_set(new_best, mpath_count - 1);
if (mpath_changed || (bgp_info_mpath_count (new_best) != old_mpath_count))
if (mpath_changed
|| (bgp_info_mpath_count(new_best) != old_mpath_count))
SET_FLAG(new_best->flags, BGP_INFO_MULTIPATH_CHG);
}
}
@ -620,16 +612,15 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
* Clean up multipath information for BGP_INFO_DMED_SELECTED path that
* is not selected as best path
*/
void
bgp_mp_dmed_deselect (struct bgp_info *dmed_best)
void bgp_mp_dmed_deselect(struct bgp_info *dmed_best)
{
struct bgp_info *mpinfo, *mpnext;
if (!dmed_best)
return;
for (mpinfo = bgp_info_mpath_first (dmed_best); mpinfo; mpinfo = mpnext)
{
for (mpinfo = bgp_info_mpath_first(dmed_best); mpinfo;
mpinfo = mpnext) {
mpnext = bgp_info_mpath_next(mpinfo);
bgp_info_mpath_dequeue(mpinfo);
}
@ -651,8 +642,7 @@ bgp_mp_dmed_deselect (struct bgp_info *dmed_best)
* is no change in multipath selection and no attribute change in
* any multipath.
*/
void
bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
struct bgp_info *old_best)
{
struct bgp_info *mpinfo;
@ -663,12 +653,10 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
struct community *community, *commerge;
struct ecommunity *ecomm, *ecommerge;
struct lcommunity *lcomm, *lcommerge;
struct attr_extra *ae;
struct attr attr = {0};
if (old_best && (old_best != new_best) &&
(old_attr = bgp_info_mpath_attr (old_best)))
{
if (old_best && (old_best != new_best)
&& (old_attr = bgp_info_mpath_attr(old_best))) {
bgp_attr_unintern(&old_attr);
bgp_info_mpath_attr_set(old_best, NULL);
}
@ -676,10 +664,8 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
if (!new_best)
return;
if (!bgp_info_mpath_count (new_best))
{
if ((new_attr = bgp_info_mpath_attr (new_best)))
{
if (!bgp_info_mpath_count(new_best)) {
if ((new_attr = bgp_info_mpath_attr(new_best))) {
bgp_attr_unintern(&new_attr);
bgp_info_mpath_attr_set(new_best, NULL);
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
@ -689,97 +675,91 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
bgp_attr_dup(&attr, new_best->attr);
if (new_best->peer &&
bgp_flag_check (new_best->peer->bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET))
{
if (new_best->peer && bgp_flag_check(new_best->peer->bgp,
BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
/* aggregate attribute from multipath constituents */
aspath = aspath_dup(attr.aspath);
origin = attr.origin;
community = attr.community ? community_dup (attr.community) : NULL;
ae = attr.extra;
ecomm = (ae && ae->ecommunity) ? ecommunity_dup (ae->ecommunity) : NULL;
lcomm = (ae && ae->lcommunity) ? lcommunity_dup (ae->lcommunity) : NULL;
community =
attr.community ? community_dup(attr.community) : NULL;
ecomm = (attr.ecommunity) ? ecommunity_dup(attr.ecommunity)
: NULL;
lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
: NULL;
for (mpinfo = bgp_info_mpath_first(new_best); mpinfo;
mpinfo = bgp_info_mpath_next (mpinfo))
{
asmerge = aspath_aggregate (aspath, mpinfo->attr->aspath);
mpinfo = bgp_info_mpath_next(mpinfo)) {
asmerge =
aspath_aggregate(aspath, mpinfo->attr->aspath);
aspath_free(aspath);
aspath = asmerge;
if (origin < mpinfo->attr->origin)
origin = mpinfo->attr->origin;
if (mpinfo->attr->community)
{
if (community)
{
commerge = community_merge (community, mpinfo->attr->community);
community = community_uniq_sort (commerge);
if (mpinfo->attr->community) {
if (community) {
commerge = community_merge(
community,
mpinfo->attr->community);
community =
community_uniq_sort(commerge);
community_free(commerge);
}
else
community = community_dup (mpinfo->attr->community);
} else
community = community_dup(
mpinfo->attr->community);
}
ae = mpinfo->attr->extra;
if (ae && ae->ecommunity)
{
if (ecomm)
{
ecommerge = ecommunity_merge (ecomm, ae->ecommunity);
if (mpinfo->attr->ecommunity) {
if (ecomm) {
ecommerge = ecommunity_merge(
ecomm,
mpinfo->attr->ecommunity);
ecomm = ecommunity_uniq_sort(ecommerge);
ecommunity_free(&ecommerge);
} else
ecomm = ecommunity_dup(
mpinfo->attr->ecommunity);
}
else
ecomm = ecommunity_dup (ae->ecommunity);
}
if (ae && ae->lcommunity)
{
if (lcomm)
{
lcommerge = lcommunity_merge (lcomm, ae->lcommunity);
if (mpinfo->attr->lcommunity) {
if (lcomm) {
lcommerge = lcommunity_merge(
lcomm,
mpinfo->attr->lcommunity);
lcomm = lcommunity_uniq_sort(lcommerge);
lcommunity_free(&lcommerge);
}
else
lcomm = lcommunity_dup (ae->lcommunity);
} else
lcomm = lcommunity_dup(
mpinfo->attr->lcommunity);
}
}
attr.aspath = aspath;
attr.origin = origin;
if (community)
{
if (community) {
attr.community = community;
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
}
if (ecomm)
{
ae = bgp_attr_extra_get (&attr);
ae->ecommunity = ecomm;
if (ecomm) {
attr.ecommunity = ecomm;
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
/* Zap multipath attr nexthop so we set nexthop to self */
attr.nexthop.s_addr = 0;
if (attr.extra)
memset (&attr.extra->mp_nexthop_global, 0, sizeof (struct in6_addr));
memset(&attr.mp_nexthop_global, 0, sizeof(struct in6_addr));
/* TODO: should we set ATOMIC_AGGREGATE and AGGREGATOR? */
}
new_attr = bgp_attr_intern(&attr);
bgp_attr_extra_free (&attr);
if (new_attr != bgp_info_mpath_attr (new_best))
{
if (new_attr != bgp_info_mpath_attr(new_best)) {
if ((old_attr = bgp_info_mpath_attr(new_best)))
bgp_attr_unintern(&old_attr);
bgp_info_mpath_attr_set(new_best, new_attr);
SET_FLAG(new_best->flags, BGP_INFO_ATTR_CHANGED);
}
else
} else
bgp_attr_unintern(&new_attr);
}

View File

@ -25,8 +25,7 @@
/* Supplemental information linked to bgp_info for keeping track of
* multipath selections, lazily allocated to save memory
*/
struct bgp_info_mpath
{
struct bgp_info_mpath {
/* Points to the first multipath (on bestpath) or the next multipath */
struct bgp_info_mpath *mp_next;

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* MPLS-VPN
* Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
*
* This file is part of GNU Zebra.
* This file is part of GxNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -22,15 +22,7 @@
#define _QUAGGA_BGP_MPLSVPN_H
#include "bgpd/bgp_route.h"
#define RD_TYPE_AS 0
#define RD_TYPE_IP 1
#define RD_TYPE_AS4 2
#if ENABLE_BGP_VNC
#define RD_TYPE_VNC_ETH 0xff00 /* VNC L2VPN */
#endif
#define RD_ADDRSTRLEN 28
#include "bgpd/bgp_rd.h"
#ifdef MPLS_LABEL_MAX
#undef MPLS_LABEL_MAX
@ -56,66 +48,31 @@ typedef enum {
MPLS_LABEL_ILLEGAL = 0xFFFFFFFF /* for internal use only */
} mpls_special_label_t;
#define MPLS_LABEL_IS_SPECIAL(label) \
((label) <= MPLS_LABEL_EXTENSION)
#define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
#define MPLS_LABEL_IS_NULL(label) \
((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL || \
(label) == MPLS_LABEL_IPV6_EXPLICIT_NULL || \
(label) == MPLS_LABEL_IMPLICIT_NULL)
((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \
|| (label) == MPLS_LABEL_IPV6_EXPLICIT_NULL \
|| (label) == MPLS_LABEL_IMPLICIT_NULL)
#define BGP_VPNVX_HELP_STR \
"Address Family\n" \
"Address Family\n"
#define V4_HEADER \
" Network Next Hop Metric LocPrf Weight Path"
#define V4_HEADER_TAG \
" Network Next Hop In tag/Out tag"
" Network Next Hop Metric LocPrf Weight Path\n"
#define V4_HEADER_TAG " Network Next Hop In tag/Out tag\n"
#define V4_HEADER_OVERLAY \
" Network Next Hop EthTag Overlay Index RouterMac"
" Network Next Hop EthTag Overlay Index RouterMac\n"
struct rd_as
{
u_int16_t type;
as_t as;
u_int32_t val;
};
struct rd_ip
{
u_int16_t type;
struct in_addr ip;
u_int16_t val;
};
#if ENABLE_BGP_VNC
struct rd_vnc_eth
{
u_int16_t type;
uint8_t local_nve_id;
struct ethaddr macaddr;
};
#endif
extern u_int16_t decode_rd_type (u_char *);
extern void encode_rd_type (u_int16_t, u_char *);
extern void bgp_mplsvpn_init(void);
extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
extern u_int32_t decode_label (u_char *);
extern void encode_label(u_int32_t, u_char *);
extern void decode_rd_as (u_char *, struct rd_as *);
extern void decode_rd_as4 (u_char *, struct rd_as *);
extern void decode_rd_ip (u_char *, struct rd_ip *);
#if ENABLE_BGP_VNC
extern void
decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
#endif
extern int str2prefix_rd (const char *, struct prefix_rd *);
extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
extern u_int32_t decode_label(mpls_label_t *);
extern void encode_label(mpls_label_t, mpls_label_t *);
extern int
argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi);
extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
int *index, afi_t *afi);
extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
enum bgp_show_type type, void *output_arg, int tags, u_char use_json);
enum bgp_show_type type, void *output_arg,
int tags, u_char use_json);
#endif /* _QUAGGA_BGP_MPLSVPN_H */

View File

@ -47,8 +47,7 @@ extern struct zebra_privs_t bgpd_privs;
static int bgp_bind(struct peer *);
/* BGP listening socket. */
struct bgp_listener
{
struct bgp_listener {
int fd;
union sockunion su;
struct thread *thread;
@ -58,8 +57,8 @@ struct bgp_listener
* Set MD5 key for the socket, for the given IPv4 peer address.
* If the password is NULL or zero-length, the option will be disabled.
*/
static int
bgp_md5_set_socket (int socket, union sockunion *su, const char *password)
static int bgp_md5_set_socket(int socket, union sockunion *su,
const char *password)
{
int ret = -1;
int en = ENOSYS;
@ -81,20 +80,20 @@ bgp_md5_set_socket (int socket, union sockunion *su, const char *password)
#endif /* HAVE_TCP_MD5SIG */
if (ret < 0)
zlog_warn ("can't set TCP_MD5SIG option on socket %d: %s", socket, safe_strerror (en));
zlog_warn("can't set TCP_MD5SIG option on socket %d: %s",
socket, safe_strerror(en));
return ret;
}
/* Helper for bgp_connect */
static int
bgp_md5_set_connect (int socket, union sockunion *su, const char *password)
static int bgp_md5_set_connect(int socket, union sockunion *su,
const char *password)
{
int ret = -1;
#if HAVE_DECL_TCP_MD5SIG
if ( bgpd_privs.change (ZPRIVS_RAISE) )
{
if (bgpd_privs.change(ZPRIVS_RAISE)) {
zlog_err("%s: could not raise privs", __func__);
return ret;
}
@ -108,26 +107,25 @@ bgp_md5_set_connect (int socket, union sockunion *su, const char *password)
return ret;
}
static int
bgp_md5_set_password (struct peer *peer, const char *password)
static int bgp_md5_set_password(struct peer *peer, const char *password)
{
struct listnode *node;
int ret = 0;
struct bgp_listener *listener;
if ( bgpd_privs.change (ZPRIVS_RAISE) )
{
if (bgpd_privs.change(ZPRIVS_RAISE)) {
zlog_err("%s: could not raise privs", __func__);
return -1;
}
/* Set or unset the password on the listen socket(s). Outbound connections
/* Set or unset the password on the listen socket(s). Outbound
* connections
* are taken care of in bgp_connect() below.
*/
for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
if (listener->su.sa.sa_family == peer->su.sa.sa_family)
{
ret = bgp_md5_set_socket (listener->fd, &peer->su, password);
if (listener->su.sa.sa_family == peer->su.sa.sa_family) {
ret = bgp_md5_set_socket(listener->fd, &peer->su,
password);
break;
}
@ -137,60 +135,55 @@ bgp_md5_set_password (struct peer *peer, const char *password)
return ret;
}
int
bgp_md5_set (struct peer *peer)
int bgp_md5_set(struct peer *peer)
{
/* Set the password from listen socket. */
return bgp_md5_set_password(peer, peer->password);
}
int
bgp_md5_unset (struct peer *peer)
int bgp_md5_unset(struct peer *peer)
{
/* Unset the password from listen socket. */
return bgp_md5_set_password(peer, NULL);
}
int
bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
{
char buf[INET_ADDRSTRLEN];
int ret = 0;
/* In case of peer is EBGP, we should set TTL for this connection. */
if (!peer->gtsm_hops && (peer_sort (peer) == BGP_PEER_EBGP))
{
if (!peer->gtsm_hops && (peer_sort(peer) == BGP_PEER_EBGP)) {
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl);
if (ret)
{
zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
if (ret) {
zlog_err(
"%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__, inet_ntop(AF_INET, &peer->remote_id,
buf, sizeof(buf)),
errno);
return ret;
}
}
else if (peer->gtsm_hops)
{
/* On Linux, setting minttl without setting ttl seems to mess with the
} else if (peer->gtsm_hops) {
/* On Linux, setting minttl without setting ttl seems to mess
with the
outgoing ttl. Therefore setting both.
*/
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL);
if (ret)
{
zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
if (ret) {
zlog_err(
"%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__, inet_ntop(AF_INET, &peer->remote_id,
buf, sizeof(buf)),
errno);
return ret;
}
ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock,
MAXTTL + 1 - peer->gtsm_hops);
if (ret)
{
zlog_err ("%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
if (ret) {
zlog_err(
"%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
__func__, inet_ntop(AF_INET, &peer->remote_id,
buf, sizeof(buf)),
errno);
return ret;
}
@ -206,13 +199,13 @@ bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
* which the incoming connection is bound to. This could either be a VRF
* or it could be an interface, which in turn determines the VRF.
*/
static int
bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst)
{
#ifndef SO_BINDTODEVICE
/* only Linux has SO_BINDTODEVICE, but we're in Linux-specific code here
* anyway since the assumption is that the interface name returned by
* getsockopt() is useful in identifying the VRF, particularly with Linux's
* getsockopt() is useful in identifying the VRF, particularly with
* Linux's
* VRF l3master device. The whole mechanism is specific to Linux, so...
* when other platforms add VRF support, this will need handling here as
* well. (or, some restructuring) */
@ -229,8 +222,7 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
*bgp_inst = NULL;
name[0] = '\0';
rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
if (rc != 0)
{
if (rc != 0) {
#if defined(HAVE_CUMULUS)
zlog_err("[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
safe_strerror(errno), sock);
@ -238,16 +230,14 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
#endif
}
if (!strlen(name))
{
if (!strlen(name)) {
*bgp_inst = bgp_get_default();
return 0; /* default instance. */
}
/* First try match to instance; if that fails, check for interfaces. */
bgp = bgp_lookup_by_name(name);
if (bgp)
{
if (bgp) {
if (!bgp->vrf_id) // unexpected
return -1;
*bgp_inst = bgp;
@ -255,16 +245,14 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
}
/* TODO - This will be optimized once interfaces move into the NS */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
struct interface *ifp;
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
continue;
ifp = if_lookup_by_name(name, bgp->vrf_id);
if (ifp)
{
if (ifp) {
*bgp_inst = bgp;
return 0;
}
@ -276,8 +264,7 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
}
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
static int bgp_accept(struct thread *thread)
{
int bgp_sock;
int accept_sock;
@ -292,8 +279,7 @@ bgp_accept (struct thread *thread)
/* Register accept thread. */
accept_sock = THREAD_FD(thread);
if (accept_sock < 0)
{
if (accept_sock < 0) {
zlog_err("accept_sock is nevative value %d", accept_sock);
return -1;
}
@ -303,18 +289,18 @@ bgp_accept (struct thread *thread)
/* Accept client connection. */
bgp_sock = sockunion_accept(accept_sock, &su);
if (bgp_sock < 0)
{
zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
if (bgp_sock < 0) {
zlog_err("[Error] BGP socket accept failed (%s)",
safe_strerror(errno));
return -1;
}
set_nonblocking(bgp_sock);
/* Obtain BGP instance this connection is meant for. */
if (bgp_get_instance_for_inc_conn (bgp_sock, &bgp))
{
if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) {
if (bgp_debug_neighbor_events(NULL))
zlog_debug ("[Event] Could not get instance for incoming conn from %s",
zlog_debug(
"[Event] Could not get instance for incoming conn from %s",
inet_sutop(&su, buf));
close(bgp_sock);
return -1;
@ -326,15 +312,14 @@ bgp_accept (struct thread *thread)
/* Check remote IP address */
peer1 = peer_lookup(bgp, &su);
if (! peer1)
{
if (!peer1) {
peer1 = peer_lookup_dynamic_neighbor(bgp, &su);
if (peer1)
{
if (peer1) {
/* Dynamic neighbor has been created, let it proceed */
peer1->fd = bgp_sock;
bgp_fsm_change_status(peer1, Active);
BGP_TIMER_OFF(peer1->t_start); /* created in peer_create() */
BGP_TIMER_OFF(
peer1->t_start); /* created in peer_create() */
if (peer_active(peer1))
BGP_EVENT_ADD(peer1, TCP_connection_open);
@ -343,11 +328,10 @@ bgp_accept (struct thread *thread)
}
}
if (! peer1)
{
if (bgp_debug_neighbor_events(NULL))
{
zlog_debug ("[Event] %s connection rejected - not configured"
if (!peer1) {
if (bgp_debug_neighbor_events(NULL)) {
zlog_debug(
"[Event] %s connection rejected - not configured"
" and not valid for dynamic",
inet_sutop(&su, buf));
}
@ -355,10 +339,10 @@ bgp_accept (struct thread *thread)
return -1;
}
if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN))
{
if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)) {
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("[Event] connection from %s rejected due to admin shutdown",
zlog_debug(
"[Event] connection from %s rejected due to admin shutdown",
inet_sutop(&su, buf));
close(bgp_sock);
return -1;
@ -370,20 +354,20 @@ bgp_accept (struct thread *thread)
* Established and then the Clearing_Completed event is generated. Also,
* block incoming connection in Deleted state.
*/
if (peer1->status == Clearing || peer1->status == Deleted)
{
if (peer1->status == Clearing || peer1->status == Deleted) {
if (bgp_debug_neighbor_events(peer1))
zlog_debug("[Event] Closing incoming conn for %s (%p) state %d",
zlog_debug(
"[Event] Closing incoming conn for %s (%p) state %d",
peer1->host, peer1, peer1->status);
close(bgp_sock);
return -1;
}
/* Check that at least one AF is activated for the peer. */
if (!peer_active (peer1))
{
if (!peer_active(peer1)) {
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("%s - incoming conn rejected - no AF activated for peer",
zlog_debug(
"%s - incoming conn rejected - no AF activated for peer",
peer1->host);
close(bgp_sock);
return -1;
@ -393,20 +377,22 @@ bgp_accept (struct thread *thread)
zlog_debug("[Event] BGP connection from host %s fd %d",
inet_sutop(&su, buf), bgp_sock);
if (peer1->doppelganger)
{
if (peer1->doppelganger) {
/* We have an existing connection. Kill the existing one and run
with this one.
*/
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("[Event] New active connection from peer %s, Killing"
" previous active connection", peer1->host);
zlog_debug(
"[Event] New active connection from peer %s, Killing"
" previous active connection",
peer1->host);
peer_delete(peer1->doppelganger);
}
if (bgp_set_socket_ttl(peer1, bgp_sock) < 0)
if (bgp_debug_neighbor_events(peer1))
zlog_debug ("[Event] Unable to set min/max TTL on peer %s, Continuing",
zlog_debug(
"[Event] Unable to set min/max TTL on peer %s, Continuing",
peer1->host);
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
@ -428,11 +414,12 @@ bgp_accept (struct thread *thread)
SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
/* Make dummy peer until read Open packet. */
if (peer1->status == Established &&
CHECK_FLAG (peer1->sflags, PEER_STATUS_NSF_MODE))
{
/* If we have an existing established connection with graceful restart
* capability announced with one or more address families, then drop
if (peer1->status == Established
&& CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
/* If we have an existing established connection with graceful
* restart
* capability announced with one or more address families, then
* drop
* existing established connection and move state to connect.
*/
peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
@ -440,8 +427,7 @@ bgp_accept (struct thread *thread)
bgp_event_update(peer1, TCP_connection_closed);
}
if (peer_active (peer))
{
if (peer_active(peer)) {
BGP_EVENT_ADD(peer, TCP_connection_open);
}
@ -449,8 +435,7 @@ bgp_accept (struct thread *thread)
}
/* BGP socket bind. */
static int
bgp_bind (struct peer *peer)
static int bgp_bind(struct peer *peer)
{
#ifdef SO_BINDTODEVICE
int ret;
@ -461,8 +446,8 @@ bgp_bind (struct peer *peer)
if (!peer->bgp->vrf_id && !peer->ifname && !peer->conf_if)
return 0;
if (peer->su.sa.sa_family != AF_INET &&
peer->su.sa.sa_family != AF_INET6)
if (peer->su.sa.sa_family != AF_INET
&& peer->su.sa.sa_family != AF_INET6)
return 0; // unexpected
/* For IPv6 peering, interface (unnumbered or link-local with interface)
@ -470,8 +455,9 @@ bgp_bind (struct peer *peer)
* VRF are the situations to bind.
*/
if (peer->su.sa.sa_family == AF_INET6)
name = (peer->conf_if ? peer->conf_if : \
(peer->ifname ? peer->ifname : peer->bgp->name));
name = (peer->conf_if ? peer->conf_if
: (peer->ifname ? peer->ifname
: peer->bgp->name));
else
name = peer->ifname ? peer->ifname : peer->bgp->name;
@ -484,25 +470,24 @@ bgp_bind (struct peer *peer)
if (bgpd_privs.change(ZPRIVS_RAISE))
zlog_err("bgp_bind: could not raise privs");
ret = setsockopt (peer->fd, SOL_SOCKET, SO_BINDTODEVICE,
name, strlen(name));
ret = setsockopt(peer->fd, SOL_SOCKET, SO_BINDTODEVICE, name,
strlen(name));
myerrno = errno;
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("bgp_bind: could not lower privs");
if (ret < 0)
{
if (ret < 0) {
if (bgp_debug_neighbor_events(peer))
zlog_debug ("bind to interface %s failed, errno=%d", name, myerrno);
zlog_debug("bind to interface %s failed, errno=%d",
name, myerrno);
return ret;
}
#endif /* SO_BINDTODEVICE */
return 0;
}
static int
bgp_update_address (struct interface *ifp, const union sockunion *dst,
static int bgp_update_address(struct interface *ifp, const union sockunion *dst,
union sockunion *addr)
{
struct prefix *p, *sel, d;
@ -514,13 +499,11 @@ bgp_update_address (struct interface *ifp, const union sockunion *dst,
sel = NULL;
common = -1;
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
{
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
p = connected->address;
if (p->family != d.family)
continue;
if (prefix_common_bits (p, &d) > common)
{
if (prefix_common_bits(p, &d) > common) {
sel = p;
common = prefix_common_bits(sel, &d);
}
@ -534,8 +517,7 @@ bgp_update_address (struct interface *ifp, const union sockunion *dst,
}
/* Update source selection. */
static int
bgp_update_source (struct peer *peer)
static int bgp_update_source(struct peer *peer)
{
struct interface *ifp;
union sockunion addr;
@ -544,8 +526,7 @@ bgp_update_source (struct peer *peer)
sockunion_init(&addr);
/* Source is specified with interface name. */
if (peer->update_if)
{
if (peer->update_if) {
ifp = if_lookup_by_name(peer->update_if, peer->bgp->vrf_id);
if (!ifp)
return -1;
@ -558,7 +539,8 @@ bgp_update_source (struct peer *peer)
/* Source is specified with IP address. */
if (peer->update_source)
ret = sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source);
ret = sockunion_bind(peer->fd, peer->update_source, 0,
peer->update_source);
return ret;
}
@ -566,13 +548,11 @@ bgp_update_source (struct peer *peer)
#define DATAPLANE_MARK 254 /* main table ID */
/* BGP try to connect to the peer. */
int
bgp_connect (struct peer *peer)
int bgp_connect(struct peer *peer)
{
ifindex_t ifindex = 0;
if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer))
{
if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) {
zlog_debug("Peer address not learnt: Returning from connect");
return 0;
}
@ -592,8 +572,8 @@ bgp_connect (struct peer *peer)
sockopt_reuseaddr(peer->fd);
sockopt_reuseport(peer->fd);
if (sockopt_mark_default(peer->fd, DATAPLANE_MARK, &bgpd_privs) < 0)
zlog_warn("Unable to set mark on FD for peer %s, err=%s", peer->host,
safe_strerror(errno));
zlog_warn("Unable to set mark on FD for peer %s, err=%s",
peer->host, safe_strerror(errno));
#ifdef IPTOS_PREC_INTERNETCONTROL
if (bgpd_privs.change(ZPRIVS_RAISE))
@ -613,48 +593,49 @@ bgp_connect (struct peer *peer)
bgp_bind(peer);
/* Update source bind. */
if (bgp_update_source (peer) < 0)
{
if (bgp_update_source(peer) < 0) {
return connect_error;
}
if (peer->conf_if || peer->ifname)
ifindex = ifname2ifindex (peer->conf_if ? peer->conf_if : peer->ifname, peer->bgp->vrf_id);
ifindex = ifname2ifindex(peer->conf_if ? peer->conf_if
: peer->ifname,
peer->bgp->vrf_id);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s [Event] Connect start to %s fd %d",
peer->host, peer->host, peer->fd);
zlog_debug("%s [Event] Connect start to %s fd %d", peer->host,
peer->host, peer->fd);
/* Connect to the remote peer. */
return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
return sockunion_connect(peer->fd, &peer->su, htons(peer->port),
ifindex);
}
/* After TCP connection is established. Get local address and port. */
int
bgp_getsockname (struct peer *peer)
{
if (peer->su_local)
int bgp_getsockname(struct peer *peer)
{
if (peer->su_local) {
sockunion_free(peer->su_local);
peer->su_local = NULL;
}
if (peer->su_remote)
{
if (peer->su_remote) {
sockunion_free(peer->su_remote);
peer->su_remote = NULL;
}
peer->su_local = sockunion_getsockname(peer->fd);
if (!peer->su_local) return -1;
if (!peer->su_local)
return -1;
peer->su_remote = sockunion_getpeername(peer->fd);
if (!peer->su_remote) return -1;
if (!peer->su_remote)
return -1;
if (bgp_nexthop_set (peer->su_local, peer->su_remote,
&peer->nexthop, peer))
{
if (bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop,
peer)) {
#if defined(HAVE_CUMULUS)
zlog_err ("%s: nexthop_set failed, resetting connection - intf %p",
zlog_err(
"%s: nexthop_set failed, resetting connection - intf %p",
peer->host, peer->nexthop.ifp);
return -1;
#endif
@ -664,8 +645,7 @@ bgp_getsockname (struct peer *peer)
}
static int
bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen)
{
struct bgp_listener *listener;
int ret, en;
@ -690,15 +670,13 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("%s: could not lower privs", __func__);
if (ret < 0)
{
if (ret < 0) {
zlog_err("bind: %s", safe_strerror(en));
return ret;
}
ret = listen(sock, 3);
if (ret < 0)
{
if (ret < 0) {
zlog_err("listen: %s", safe_strerror(errno));
return ret;
}
@ -707,15 +685,15 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
listener->fd = sock;
memcpy(&listener->su, sa, salen);
listener->thread = NULL;
thread_add_read(bm->master, bgp_accept, listener, sock, &listener->thread);
thread_add_read(bm->master, bgp_accept, listener, sock,
&listener->thread);
listnode_add(bm->listen_sockets, listener);
return 0;
}
/* IPv6 supported version of BGP server socket setup. */
int
bgp_socket (unsigned short port, const char *address)
int bgp_socket(unsigned short port, const char *address)
{
struct addrinfo *ainfo;
struct addrinfo *ainfo_save;
@ -731,28 +709,27 @@ bgp_socket (unsigned short port, const char *address)
port_str[sizeof(port_str) - 1] = '\0';
ret = getaddrinfo(address, port_str, &req, &ainfo_save);
if (ret != 0)
{
if (ret != 0) {
zlog_err("getaddrinfo: %s", gai_strerror(ret));
return -1;
}
count = 0;
for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next)
{
for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next) {
int sock;
if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
continue;
sock = socket (ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
if (sock < 0)
{
sock = socket(ainfo->ai_family, ainfo->ai_socktype,
ainfo->ai_protocol);
if (sock < 0) {
zlog_err("socket: %s", safe_strerror(errno));
continue;
}
/* if we intend to implement ttl-security, this socket needs ttl=255 */
/* if we intend to implement ttl-security, this socket needs
* ttl=255 */
sockopt_ttl(ainfo->ai_family, sock, MAXTTL);
ret = bgp_listener(sock, ainfo->ai_addr, ainfo->ai_addrlen);
@ -762,8 +739,7 @@ bgp_socket (unsigned short port, const char *address)
close(sock);
}
freeaddrinfo(ainfo_save);
if (count == 0)
{
if (count == 0) {
zlog_err("%s: no usable addresses", __func__);
return -1;
}
@ -771,8 +747,7 @@ bgp_socket (unsigned short port, const char *address)
return 0;
}
void
bgp_close (void)
void bgp_close(void)
{
struct listnode *node, *next;
struct bgp_listener *listener;
@ -780,8 +755,7 @@ bgp_close (void)
if (bm->listen_sockets == NULL)
return;
for (ALL_LIST_ELEMENTS (bm->listen_sockets, node, next, listener))
{
for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
thread_cancel(listener->thread);
close(listener->fd);
listnode_delete(bm->listen_sockets, listener);

View File

@ -47,46 +47,41 @@
#include "zebra/rib.h"
#include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
char *
bnc_str (struct bgp_nexthop_cache *bnc, char *buf, int size)
char *bnc_str(struct bgp_nexthop_cache *bnc, char *buf, int size)
{
prefix2str(&(bnc->node->p), buf, size);
return buf;
}
void
bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
void bnc_nexthop_free(struct bgp_nexthop_cache *bnc)
{
nexthops_free(bnc->nexthop);
}
struct bgp_nexthop_cache *
bnc_new (void)
struct bgp_nexthop_cache *bnc_new(void)
{
struct bgp_nexthop_cache *bnc;
bnc = XCALLOC (MTYPE_BGP_NEXTHOP_CACHE, sizeof (struct bgp_nexthop_cache));
bnc = XCALLOC(MTYPE_BGP_NEXTHOP_CACHE,
sizeof(struct bgp_nexthop_cache));
LIST_INIT(&(bnc->paths));
return bnc;
}
void
bnc_free (struct bgp_nexthop_cache *bnc)
void bnc_free(struct bgp_nexthop_cache *bnc)
{
bnc_nexthop_free(bnc);
XFREE(MTYPE_BGP_NEXTHOP_CACHE, bnc);
}
/* Reset and free all BGP nexthop cache. */
static void
bgp_nexthop_cache_reset (struct bgp_table *table)
static void bgp_nexthop_cache_reset(struct bgp_table *table)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
if ((bnc = rn->info) != NULL)
{
if ((bnc = rn->info) != NULL) {
bnc_free(bnc);
rn->info = NULL;
bgp_unlock_node(rn);
@ -94,14 +89,12 @@ bgp_nexthop_cache_reset (struct bgp_table *table)
}
/* BGP own address structure */
struct bgp_addr
{
struct bgp_addr {
struct in_addr addr;
int refcnt;
};
static void *
bgp_address_hash_alloc (void *p)
static void *bgp_address_hash_alloc(void *p)
{
const struct in_addr *val = (const struct in_addr *)p;
struct bgp_addr *addr;
@ -113,22 +106,19 @@ bgp_address_hash_alloc (void *p)
return addr;
}
static void
bgp_address_hash_free (void *addr)
static void bgp_address_hash_free(void *addr)
{
XFREE(MTYPE_BGP_ADDR, addr);
}
static unsigned int
bgp_address_hash_key_make (void *p)
static unsigned int bgp_address_hash_key_make(void *p)
{
const struct bgp_addr *addr = p;
return jhash_1word(addr->addr.s_addr, 0);
}
static int
bgp_address_hash_cmp (const void *p1, const void *p2)
static int bgp_address_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_addr *addr1 = p1;
const struct bgp_addr *addr2 = p2;
@ -136,15 +126,13 @@ bgp_address_hash_cmp (const void *p1, const void *p2)
return addr1->addr.s_addr == addr2->addr.s_addr;
}
void
bgp_address_init (struct bgp *bgp)
void bgp_address_init(struct bgp *bgp)
{
bgp->address_hash = hash_create(bgp_address_hash_key_make,
bgp_address_hash_cmp, NULL);
}
void
bgp_address_destroy (struct bgp *bgp)
void bgp_address_destroy(struct bgp *bgp)
{
if (bgp->address_hash == NULL)
return;
@ -153,8 +141,7 @@ bgp_address_destroy (struct bgp *bgp)
bgp->address_hash = NULL;
}
static void
bgp_address_add (struct bgp *bgp, struct prefix *p)
static void bgp_address_add(struct bgp *bgp, struct prefix *p)
{
struct bgp_addr tmp;
struct bgp_addr *addr;
@ -168,8 +155,7 @@ bgp_address_add (struct bgp *bgp, struct prefix *p)
addr->refcnt++;
}
static void
bgp_address_del (struct bgp *bgp, struct prefix *p)
static void bgp_address_del(struct bgp *bgp, struct prefix *p)
{
struct bgp_addr tmp;
struct bgp_addr *addr;
@ -183,21 +169,18 @@ bgp_address_del (struct bgp *bgp, struct prefix *p)
addr->refcnt--;
if (addr->refcnt == 0)
{
if (addr->refcnt == 0) {
hash_release(bgp->address_hash, addr);
XFREE(MTYPE_BGP_ADDR, addr);
}
}
struct bgp_connected_ref
{
struct bgp_connected_ref {
unsigned int refcnt;
};
void
bgp_connected_add (struct bgp *bgp, struct connected *ifc)
void bgp_connected_add(struct bgp *bgp, struct connected *ifc)
{
struct prefix p;
struct prefix *addr;
@ -209,8 +192,7 @@ bgp_connected_add (struct bgp *bgp, struct connected *ifc)
addr = ifc->address;
p = *(CONNECTED_PREFIX(ifc));
if (addr->family == AF_INET)
{
if (addr->family == AF_INET) {
apply_mask_ipv4((struct prefix_ipv4 *)&p);
if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
@ -218,33 +200,30 @@ bgp_connected_add (struct bgp *bgp, struct connected *ifc)
bgp_address_add(bgp, addr);
rn = bgp_node_get (bgp->connected_table[AFI_IP], (struct prefix *) &p);
if (rn->info)
{
rn = bgp_node_get(bgp->connected_table[AFI_IP],
(struct prefix *)&p);
if (rn->info) {
bc = rn->info;
bc->refcnt++;
}
else
{
bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
} else {
bc = XCALLOC(MTYPE_BGP_CONN,
sizeof(struct bgp_connected_ref));
bc->refcnt = 1;
rn->info = bc;
}
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0) &&
peer->status != Established &&
!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
{
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (peer->conf_if
&& (strcmp(peer->conf_if, ifc->ifp->name) == 0)
&& peer->status != Established
&& !CHECK_FLAG(peer->flags,
PEER_FLAG_IFPEER_V6ONLY)) {
if (peer_active(peer))
BGP_EVENT_ADD(peer, BGP_Stop);
BGP_EVENT_ADD(peer, BGP_Start);
}
}
}
else if (addr->family == AF_INET6)
{
} else if (addr->family == AF_INET6) {
apply_mask_ipv6((struct prefix_ipv6 *)&p);
if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
@ -253,23 +232,21 @@ bgp_connected_add (struct bgp *bgp, struct connected *ifc)
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
return;
rn = bgp_node_get (bgp->connected_table[AFI_IP6], (struct prefix *) &p);
if (rn->info)
{
rn = bgp_node_get(bgp->connected_table[AFI_IP6],
(struct prefix *)&p);
if (rn->info) {
bc = rn->info;
bc->refcnt++;
}
else
{
bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
} else {
bc = XCALLOC(MTYPE_BGP_CONN,
sizeof(struct bgp_connected_ref));
bc->refcnt = 1;
rn->info = bc;
}
}
}
void
bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
void bgp_connected_delete(struct bgp *bgp, struct connected *ifc)
{
struct prefix p;
struct prefix *addr;
@ -279,8 +256,7 @@ bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
addr = ifc->address;
p = *(CONNECTED_PREFIX(ifc));
if (addr->family == AF_INET)
{
if (addr->family == AF_INET) {
apply_mask_ipv4((struct prefix_ipv4 *)&p);
if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
@ -294,16 +270,13 @@ bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
bc = rn->info;
bc->refcnt--;
if (bc->refcnt == 0)
{
if (bc->refcnt == 0) {
XFREE(MTYPE_BGP_CONN, bc);
rn->info = NULL;
}
bgp_unlock_node(rn);
bgp_unlock_node(rn);
}
else if (addr->family == AF_INET6)
{
} else if (addr->family == AF_INET6) {
apply_mask_ipv6((struct prefix_ipv6 *)&p);
if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
@ -312,14 +285,14 @@ bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
return;
rn = bgp_node_lookup (bgp->connected_table[AFI_IP6], (struct prefix *) &p);
rn = bgp_node_lookup(bgp->connected_table[AFI_IP6],
(struct prefix *)&p);
if (!rn)
return;
bc = rn->info;
bc->refcnt--;
if (bc->refcnt == 0)
{
if (bc->refcnt == 0) {
XFREE(MTYPE_BGP_CONN, bc);
rn->info = NULL;
}
@ -328,12 +301,11 @@ bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
}
}
int
bgp_nexthop_self (struct bgp *bgp, struct attr *attr)
int bgp_nexthop_self(struct bgp *bgp, struct in_addr nh_addr)
{
struct bgp_addr tmp, *addr;
tmp.addr = attr->nexthop;
tmp.addr = nh_addr;
addr = hash_lookup(bgp->address_hash, &tmp);
if (addr)
@ -342,8 +314,7 @@ bgp_nexthop_self (struct bgp *bgp, struct attr *attr)
return 0;
}
int
bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer)
{
struct bgp_node *rn1;
struct bgp_node *rn2;
@ -363,8 +334,7 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
p.u.prefix4 = peer->su.sin.sin_addr;
rn2 = bgp_node_match(peer->bgp->connected_table[AFI_IP], &p);
if (!rn2)
{
if (!rn2) {
bgp_unlock_node(rn1);
return 0;
}
@ -377,8 +347,7 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
return (ret);
}
static void
bgp_show_nexthops (struct vty *vty, struct bgp *bgp, int detail)
static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
@ -387,71 +356,105 @@ bgp_show_nexthops (struct vty *vty, struct bgp *bgp, int detail)
time_t tbuf;
afi_t afi;
vty_outln (vty, "Current BGP nexthop cache:");
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
{
vty_out(vty, "Current BGP nexthop cache:\n");
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
if (!bgp->nexthop_cache_table[afi])
continue;
for (rn = bgp_table_top (bgp->nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn))
{
if ((bnc = rn->info) != NULL)
{
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
{
vty_outln (vty, " %s valid [IGP metric %d], #paths %d",
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)),
for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn;
rn = bgp_route_next(rn)) {
if ((bnc = rn->info) != NULL) {
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) {
vty_out(vty,
" %s valid [IGP metric %d], #paths %d\n",
inet_ntop(rn->p.family,
&rn->p.u.prefix, buf,
sizeof(buf)),
bnc->metric, bnc->path_count);
if (detail)
for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
switch (nexthop->type)
{
for (nexthop = bnc->nexthop;
nexthop;
nexthop = nexthop->next)
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV6:
vty_outln (vty, " gate %s",
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, sizeof(buf)));
vty_out(vty,
" gate %s\n",
inet_ntop(
AF_INET6,
&nexthop->gate
.ipv6,
buf,
sizeof(buf)));
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
vty_outln (vty, " gate %s, if %s",
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
vty_out(vty,
" gate %s, if %s\n",
inet_ntop(
AF_INET6,
&nexthop->gate
.ipv6,
buf,
sizeof(buf)),
ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4:
vty_outln (vty, " gate %s",
inet_ntop(AF_INET, &nexthop->gate.ipv4, buf, sizeof(buf)));
vty_out(vty,
" gate %s\n",
inet_ntop(
AF_INET,
&nexthop->gate
.ipv4,
buf,
sizeof(buf)));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_outln (vty, " if %s",
ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
vty_out(vty,
" if %s\n",
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_outln (vty, " gate %s, if %s",
inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
vty_out(vty,
" gate %s, if %s\n",
inet_ntop(
AF_INET,
&nexthop->gate
.ipv4,
buf,
sizeof(buf)),
ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
default:
vty_outln (vty, " invalid nexthop type %u",
vty_out(vty,
" invalid nexthop type %u\n",
nexthop->type);
}
} else {
vty_out(vty, " %s invalid\n",
inet_ntop(rn->p.family,
&rn->p.u.prefix, buf,
sizeof(buf)));
if (CHECK_FLAG(bnc->flags,
BGP_NEXTHOP_CONNECTED))
vty_out(vty,
" Must be Connected\n");
}
else
{
vty_outln (vty, " %s invalid",
inet_ntop(rn->p.family, &rn->p.u.prefix, buf, sizeof(buf)));
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
vty_outln (vty, " Must be Connected");
}
tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
tbuf = time(NULL)
- (bgp_clock() - bnc->last_update);
vty_out(vty, " Last update: %s", ctime(&tbuf));
vty_out (vty, VTYNL);
vty_out(vty, "\n");
}
}
}
}
static int
show_ip_bgp_nexthop_table (struct vty *vty, const char *name, int detail)
static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
int detail)
{
struct bgp *bgp;
@ -459,9 +462,8 @@ show_ip_bgp_nexthop_table (struct vty *vty, const char *name, int detail)
bgp = bgp_lookup_by_name(name);
else
bgp = bgp_get_default();
if (!bgp)
{
vty_outln (vty, "%% No such BGP instance exist");
if (!bgp) {
vty_out(vty, "%% No such BGP instance exist\n");
return CMD_WARNING;
}
@ -470,17 +472,16 @@ show_ip_bgp_nexthop_table (struct vty *vty, const char *name, int detail)
return CMD_SUCCESS;
}
static void
bgp_show_all_instances_nexthops_vty (struct vty *vty)
static void bgp_show_all_instances_nexthops_vty(struct vty *vty)
{
struct listnode *node, *nnode;
struct bgp *bgp;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
vty_outln (vty, "%sInstance %s:",
VTYNL,
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? "Default" : bgp->name);
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
? "Default"
: bgp->name);
bgp_show_nexthops(vty, bgp, 0);
}
}
@ -514,33 +515,30 @@ DEFUN (show_ip_bgp_instance_all_nexthop,
return CMD_SUCCESS;
}
void
bgp_scan_init (struct bgp *bgp)
void bgp_scan_init(struct bgp *bgp)
{
afi_t afi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
{
bgp->nexthop_cache_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
bgp->nexthop_cache_table[afi] =
bgp_table_init(afi, SAFI_UNICAST);
bgp->connected_table[afi] = bgp_table_init(afi, SAFI_UNICAST);
bgp->import_check_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
bgp->import_check_table[afi] =
bgp_table_init(afi, SAFI_UNICAST);
}
}
void
bgp_scan_vty_init (void)
void bgp_scan_vty_init(void)
{
install_element(VIEW_NODE, &show_ip_bgp_nexthop_cmd);
install_element(VIEW_NODE, &show_ip_bgp_instance_all_nexthop_cmd);
}
void
bgp_scan_finish (struct bgp *bgp)
void bgp_scan_finish(struct bgp *bgp)
{
afi_t afi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
{
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
/* Only the current one needs to be reset. */
bgp_nexthop_cache_reset(bgp->nexthop_cache_table[afi]);
bgp_table_unlock(bgp->nexthop_cache_table[afi]);

View File

@ -25,20 +25,18 @@
#include "queue.h"
#include "prefix.h"
#define NEXTHOP_FAMILY(nexthop_len) ( \
((nexthop_len) == 4 || \
(nexthop_len) == 12 ? AF_INET : \
((nexthop_len) == 16 || \
(nexthop_len) == 24 || \
(nexthop_len) == 48 ? AF_INET6 : \
AF_UNSPEC)) \
)
#define NEXTHOP_FAMILY(nexthop_len) \
(((nexthop_len) == 4 || (nexthop_len) == 12 \
? AF_INET \
: ((nexthop_len) == 16 || (nexthop_len) == 24 \
|| (nexthop_len) == 48 \
? AF_INET6 \
: AF_UNSPEC)))
#define BGP_MP_NEXTHOP_FAMILY NEXTHOP_FAMILY
/* BGP nexthop cache value structure. */
struct bgp_nexthop_cache
{
struct bgp_nexthop_cache {
/* IGP route's metric. */
u_int32_t metric;
@ -74,7 +72,7 @@ extern void bgp_connected_add (struct bgp *bgp, struct connected *c);
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
extern int bgp_multiaccess_check_v4(struct in_addr, struct peer *);
extern int bgp_config_write_scan_time(struct vty *);
extern int bgp_nexthop_self (struct bgp *, struct attr *);
extern int bgp_nexthop_self(struct bgp *, struct in_addr);
extern struct bgp_nexthop_cache *bnc_new(void);
extern void bnc_free(struct bgp_nexthop_cache *bnc);
extern void bnc_nexthop_free(struct bgp_nexthop_cache *bnc);

View File

@ -53,15 +53,13 @@ static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p);
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
int keep);
static int
bgp_isvalid_nexthop (struct bgp_nexthop_cache *bnc)
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
{
return (bgp_zebra_num_connects() == 0 ||
(bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)));
return (bgp_zebra_num_connects() == 0
|| (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)));
}
int
bgp_find_nexthop (struct bgp_info *path, int connected)
int bgp_find_nexthop(struct bgp_info *path, int connected)
{
struct bgp_nexthop_cache *bnc = path->nexthop;
@ -82,18 +80,16 @@ bgp_find_nexthop (struct bgp_info *path, int connected)
return (bgp_isvalid_nexthop(bnc));
}
static void
bgp_unlink_nexthop_check (struct bgp_nexthop_cache *bnc)
{
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
{
if (BGP_DEBUG(nht, NHT))
static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
{
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info) {
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
zlog_debug("bgp_unlink_nexthop: freeing bnc %s",
bnc_str(bnc, buf, PREFIX2STR_BUFFER));
}
unregister_zebra_rnh(bnc, CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
unregister_zebra_rnh(bnc,
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
bnc->node->info = NULL;
bgp_unlock_node(bnc->node);
bnc->node = NULL;
@ -101,8 +97,7 @@ bgp_unlink_nexthop_check (struct bgp_nexthop_cache *bnc)
}
}
void
bgp_unlink_nexthop (struct bgp_info *path)
void bgp_unlink_nexthop(struct bgp_info *path)
{
struct bgp_nexthop_cache *bnc = path->nexthop;
@ -114,8 +109,7 @@ bgp_unlink_nexthop (struct bgp_info *path)
bgp_unlink_nexthop_check(bnc);
}
void
bgp_unlink_nexthop_by_peer (struct peer *peer)
void bgp_unlink_nexthop_by_peer(struct peer *peer)
{
struct prefix p;
struct bgp_node *rn;
@ -138,8 +132,7 @@ bgp_unlink_nexthop_by_peer (struct peer *peer)
bgp_unlink_nexthop_check(bnc);
}
int
bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t afi, struct bgp_info *ri,
struct peer *peer, int connected)
{
struct bgp_node *rn;
@ -147,37 +140,38 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
struct prefix p;
int is_bgp_static_route = 0;
if (ri)
{
is_bgp_static_route = ((ri->type == ZEBRA_ROUTE_BGP) &&
(ri->sub_type == BGP_ROUTE_STATIC)) ? 1 : 0;
if (ri) {
is_bgp_static_route = ((ri->type == ZEBRA_ROUTE_BGP)
&& (ri->sub_type == BGP_ROUTE_STATIC))
? 1
: 0;
/* Since Extended Next-hop Encoding (RFC5549) support, we want to derive
/* Since Extended Next-hop Encoding (RFC5549) support, we want
to derive
address-family from the next-hop. */
if (!is_bgp_static_route)
afi = BGP_ATTR_NEXTHOP_AFI_IP6(ri->attr) ? AFI_IP6 : AFI_IP;
afi = BGP_ATTR_NEXTHOP_AFI_IP6(ri->attr) ? AFI_IP6
: AFI_IP;
/* This will return TRUE if the global IPv6 NH is a link local addr */
/* This will return TRUE if the global IPv6 NH is a link local
* addr */
if (make_prefix(afi, ri, &p) < 0)
return 1;
}
else if (peer)
{
} else if (peer) {
/* Don't register link local NH */
if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr))
if (afi == AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr))
return 1;
if (! sockunion2hostprefix (&peer->su, &p))
{
if (BGP_DEBUG(nht, NHT))
{
zlog_debug("%s: Attempting to register with unknown AFI %d (not %d or %d)",
if (!sockunion2hostprefix(&peer->su, &p)) {
if (BGP_DEBUG(nht, NHT)) {
zlog_debug(
"%s: Attempting to register with unknown AFI %d (not %d or %d)",
__FUNCTION__, afi, AFI_IP, AFI_IP6);
}
return 0;
}
}
else
} else
return 0;
if (is_bgp_static_route)
@ -185,15 +179,13 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
else
rn = bgp_node_get(bgp->nexthop_cache_table[afi], &p);
if (!rn->info)
{
if (!rn->info) {
bnc = bnc_new();
rn->info = bnc;
bnc->node = rn;
bnc->bgp = bgp;
bgp_lock_node(rn);
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
zlog_debug("Allocated bnc %s peer %p",
@ -203,58 +195,54 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
bnc = rn->info;
bgp_unlock_node(rn);
if (is_bgp_static_route)
{
if (is_bgp_static_route) {
SET_FLAG(bnc->flags, BGP_STATIC_ROUTE);
/* If we're toggling the type, re-register */
if ((bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) &&
!CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
{
if ((bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK))
&& !CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)) {
SET_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
else if ((!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) &&
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
{
} else if ((!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK))
&& CHECK_FLAG(bnc->flags,
BGP_STATIC_ROUTE_EXACT_MATCH)) {
UNSET_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
}
/* When nexthop is already known, but now requires 'connected' resolution,
* re-register it. The reverse scenario where the nexthop currently requires
/* When nexthop is already known, but now requires 'connected'
* resolution,
* re-register it. The reverse scenario where the nexthop currently
* requires
* 'connected' resolution does not need a re-register (i.e., we treat
* 'connected-required' as an override) except in the scenario where this
* 'connected-required' as an override) except in the scenario where
* this
* is actually a case of tracking a peer for connectivity (e.g., after
* disable connected-check).
* NOTE: We don't track the number of paths separately for 'connected-
* required' vs 'connected-not-required' as this change is not a common
* scenario.
*/
else if (connected && ! CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
{
else if (connected && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) {
SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
else if (peer && !connected && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
{
} else if (peer && !connected
&& CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) {
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
}
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
{
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) {
bnc->flags |= BGP_NEXTHOP_REGISTERED;
bnc->flags |= BGP_NEXTHOP_VALID;
}
else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
} else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
register_zebra_rnh(bnc, is_bgp_static_route);
if (ri && ri->nexthop != bnc)
{
/* Unlink from existing nexthop cache, if any. This will also free
if (ri && ri->nexthop != bnc) {
/* Unlink from existing nexthop cache, if any. This will also
* free
* the nexthop cache entry, if appropriate.
*/
bgp_unlink_nexthop(ri);
@ -265,8 +253,7 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
(bgp_info_extra_get(ri))->igpmetric = bnc->metric;
else if (ri->extra)
ri->extra->igpmetric = 0;
}
else if (peer)
} else if (peer)
bnc->nht_info = (void *)peer; /* NHT peer reference */
/*
@ -280,8 +267,7 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
return (bgp_isvalid_nexthop(bnc));
}
void
bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
@ -297,11 +283,12 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
if (!sockunion2hostprefix(&peer->su, &p))
return;
rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
if (!rn || !rn->info)
{
rn = bgp_node_lookup(
peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
if (!rn || !rn->info) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Cannot find connected NHT node for peer %s", peer->host);
zlog_debug("Cannot find connected NHT node for peer %s",
peer->host);
if (rn)
bgp_unlock_node(rn);
return;
@ -310,18 +297,17 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
bnc = rn->info;
bgp_unlock_node(rn);
if (bnc->nht_info != peer)
{
if (bnc->nht_info != peer) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Connected NHT %p node for peer %s points to %p",
zlog_debug(
"Connected NHT %p node for peer %s points to %p",
bnc, peer->host, bnc->nht_info);
return;
}
bnc->nht_info = NULL;
if (LIST_EMPTY(&(bnc->paths)))
{
if (LIST_EMPTY(&(bnc->paths))) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Freeing connected NHT node %p for peer %s",
bnc, peer->host);
@ -332,8 +318,7 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
}
}
void
bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
{
struct stream *s;
struct bgp_node *rn = NULL;
@ -349,9 +334,10 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
struct bgp *bgp;
bgp = bgp_lookup_by_vrf_id(vrf_id);
if (!bgp)
{
zlog_err("parse nexthop update: instance not found for vrf_id %d", vrf_id);
if (!bgp) {
zlog_err(
"parse nexthop update: instance not found for vrf_id %d",
vrf_id);
return;
}
@ -360,8 +346,7 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
memset(&p, 0, sizeof(struct prefix));
p.family = stream_getw(s);
p.prefixlen = stream_getc(s);
switch (p.family)
{
switch (p.family) {
case AF_INET:
p.u.prefix4.s_addr = stream_get_ipv4(s);
break;
@ -373,17 +358,18 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
}
if (command == ZEBRA_NEXTHOP_UPDATE)
rn = bgp_node_lookup(bgp->nexthop_cache_table[family2afi(p.family)], &p);
rn = bgp_node_lookup(
bgp->nexthop_cache_table[family2afi(p.family)], &p);
else if (command == ZEBRA_IMPORT_CHECK_UPDATE)
rn = bgp_node_lookup(bgp->import_check_table[family2afi(p.family)], &p);
rn = bgp_node_lookup(
bgp->import_check_table[family2afi(p.family)], &p);
if (!rn || !rn->info)
{
if (BGP_DEBUG(nht, NHT))
{
if (!rn || !rn->info) {
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof(buf));
zlog_debug("parse nexthop update(%s): rn not found", buf);
zlog_debug("parse nexthop update(%s): rn not found",
buf);
}
if (rn)
bgp_unlock_node(rn);
@ -399,13 +385,13 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
nexthop_num = stream_getc(s);
/* debug print the input */
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof(buf));
zlog_debug("%d: Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x",
vrf_id, buf, metric, bnc->metric, nexthop_num, bnc->nexthop_num,
bnc->flags);
zlog_debug(
"%d: Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x",
vrf_id, buf, metric, bnc->metric, nexthop_num,
bnc->nexthop_num, bnc->flags);
}
if (metric != bnc->metric)
@ -414,8 +400,7 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
if (nexthop_num != bnc->nexthop_num)
bnc->change_flags |= BGP_NEXTHOP_CHANGED;
if (nexthop_num)
{
if (nexthop_num) {
/* notify bgp fsm if nbr ip goes from invalid->valid */
if (!bnc->nexthop_num)
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
@ -424,12 +409,10 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
bnc->metric = metric;
bnc->nexthop_num = nexthop_num;
for (i = 0; i < nexthop_num; i++)
{
for (i = 0; i < nexthop_num; i++) {
nexthop = nexthop_new();
nexthop->type = stream_getc(s);
switch (nexthop->type)
{
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
nexthop->gate.ipv4.s_addr = stream_get_ipv4(s);
nexthop->ifindex = stream_getl(s);
@ -454,25 +437,23 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
break;
}
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[NEXTHOP_STRLEN];
zlog_debug(" nhop via %s",
zlog_debug(
" nhop via %s",
nexthop2str(nexthop, buf, sizeof(buf)));
}
if (nhlist_tail)
{
if (nhlist_tail) {
nhlist_tail->next = nexthop;
nhlist_tail = nexthop;
}
else
{
} else {
nhlist_tail = nexthop;
nhlist_head = nexthop;
}
/* No need to evaluate the nexthop if we have already determined
/* No need to evaluate the nexthop if we have already
* determined
* that there has been a change.
*/
if (bnc->change_flags & BGP_NEXTHOP_CHANGED)
@ -487,9 +468,7 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
}
bnc_nexthop_free(bnc);
bnc->nexthop = nhlist_head;
}
else
{
} else {
bnc->flags &= ~BGP_NEXTHOP_VALID;
bnc->nexthop_num = nexthop_num;
@ -507,52 +486,46 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
* make_prefix - make a prefix structure from the path (essentially
* path's node.
*/
static int
make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p)
{
int is_bgp_static = ((ri->type == ZEBRA_ROUTE_BGP) &&
(ri->sub_type == BGP_ROUTE_STATIC)) ? 1 : 0;
int is_bgp_static = ((ri->type == ZEBRA_ROUTE_BGP)
&& (ri->sub_type == BGP_ROUTE_STATIC))
? 1
: 0;
memset(p, 0, sizeof(struct prefix));
switch (afi)
{
switch (afi) {
case AFI_IP:
p->family = AF_INET;
if (is_bgp_static)
{
if (is_bgp_static) {
p->u.prefix4 = ri->net->p.u.prefix4;
p->prefixlen = ri->net->p.prefixlen;
}
else
{
} else {
p->u.prefix4 = ri->attr->nexthop;
p->prefixlen = IPV4_MAX_BITLEN;
}
break;
case AFI_IP6:
/* We don't register link local NH */
if (ri->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL
|| IN6_IS_ADDR_LINKLOCAL (&ri->attr->extra->mp_nexthop_global))
if (ri->attr->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL
|| IN6_IS_ADDR_LINKLOCAL(&ri->attr->mp_nexthop_global))
return -1;
p->family = AF_INET6;
if (is_bgp_static)
{
if (is_bgp_static) {
p->u.prefix6 = ri->net->p.u.prefix6;
p->prefixlen = ri->net->p.prefixlen;
}
else
{
p->u.prefix6 = ri->attr->extra->mp_nexthop_global;
} else {
p->u.prefix6 = ri->attr->mp_nexthop_global;
p->prefixlen = IPV6_MAX_BITLEN;
}
break;
default:
if (BGP_DEBUG(nht, NHT))
{
zlog_debug("%s: Attempting to make prefix with unknown AFI %d (not %d or %d)",
if (BGP_DEBUG(nht, NHT)) {
zlog_debug(
"%s: Attempting to make prefix with unknown AFI %d (not %d or %d)",
__FUNCTION__, afi, AFI_IP, AFI_IP6);
}
break;
@ -569,8 +542,7 @@ make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
* RETURNS:
* void.
*/
static void
sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
{
struct stream *s;
struct prefix *p;
@ -588,16 +560,15 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
s = zclient->obuf;
stream_reset(s);
zclient_create_header(s, command, bnc->bgp->vrf_id);
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED) ||
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)
|| CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
stream_putc(s, 1);
else
stream_putc(s, 0);
stream_putw(s, PREFIX_FAMILY(p));
stream_putc(s, p->prefixlen);
switch (PREFIX_FAMILY(p))
{
switch (PREFIX_FAMILY(p)) {
case AF_INET:
stream_put_in_addr(s, &p->u.prefix4);
break;
@ -614,11 +585,11 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
if (ret < 0)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
if ((command == ZEBRA_NEXTHOP_REGISTER) ||
(command == ZEBRA_IMPORT_ROUTE_REGISTER))
if ((command == ZEBRA_NEXTHOP_REGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_REGISTER))
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
else if ((command == ZEBRA_NEXTHOP_UNREGISTER) ||
(command == ZEBRA_IMPORT_ROUTE_UNREGISTER))
else if ((command == ZEBRA_NEXTHOP_UNREGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_UNREGISTER))
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
return;
}
@ -631,8 +602,8 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
* RETURNS:
* void.
*/
static void
register_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
int is_bgp_import_route)
{
/* Check if we have already registered */
if (bnc->flags & BGP_NEXTHOP_REGISTERED)
@ -650,8 +621,8 @@ register_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
* RETURNS:
* void.
*/
static void
unregister_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
int is_bgp_import_route)
{
/* Check if we have already registered */
if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
@ -670,8 +641,7 @@ unregister_zebra_rnh (struct bgp_nexthop_cache *bnc, int is_bgp_import_route)
* RETURNS:
* void.
*/
static void
evaluate_paths (struct bgp_nexthop_cache *bnc)
static void evaluate_paths(struct bgp_nexthop_cache *bnc)
{
struct bgp_node *rn;
struct bgp_info *path;
@ -681,19 +651,19 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
struct bgp_table *table;
safi_t safi;
if (BGP_DEBUG(nht, NHT))
{
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
bnc_str(bnc, buf, PREFIX2STR_BUFFER);
zlog_debug("NH update for %s - flags 0x%x chgflags 0x%x - evaluate paths",
zlog_debug(
"NH update for %s - flags 0x%x chgflags 0x%x - evaluate paths",
buf, bnc->flags, bnc->change_flags);
}
LIST_FOREACH(path, &(bnc->paths), nh_thread)
{
if (!(path->type == ZEBRA_ROUTE_BGP &&
((path->sub_type == BGP_ROUTE_NORMAL) ||
(path->sub_type == BGP_ROUTE_STATIC))))
if (!(path->type == ZEBRA_ROUTE_BGP
&& ((path->sub_type == BGP_ROUTE_NORMAL)
|| (path->sub_type == BGP_ROUTE_STATIC))))
continue;
rn = path->net;
@ -705,38 +675,37 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
/* Path becomes valid/invalid depending on whether the nexthop
* reachable/unreachable.
*/
if ((CHECK_FLAG(path->flags, BGP_INFO_VALID) ? 1 : 0) !=
(bgp_isvalid_nexthop(bnc) ? 1 : 0))
{
if (CHECK_FLAG (path->flags, BGP_INFO_VALID))
{
bgp_aggregate_decrement (bgp, &rn->p, path, afi, safi);
if ((CHECK_FLAG(path->flags, BGP_INFO_VALID) ? 1 : 0)
!= (bgp_isvalid_nexthop(bnc) ? 1 : 0)) {
if (CHECK_FLAG(path->flags, BGP_INFO_VALID)) {
bgp_aggregate_decrement(bgp, &rn->p, path, afi,
safi);
bgp_info_unset_flag(rn, path, BGP_INFO_VALID);
}
else
{
} else {
bgp_info_set_flag(rn, path, BGP_INFO_VALID);
bgp_aggregate_increment (bgp, &rn->p, path, afi, safi);
bgp_aggregate_increment(bgp, &rn->p, path, afi,
safi);
}
}
/* Copy the metric to the path. Will be used for bestpath computation */
/* Copy the metric to the path. Will be used for bestpath
* computation */
if (bgp_isvalid_nexthop(bnc) && bnc->metric)
(bgp_info_extra_get(path))->igpmetric = bnc->metric;
else if (path->extra)
path->extra->igpmetric = 0;
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED) ||
CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
|| CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);
bgp_process(bgp, rn, afi, safi);
}
if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED))
{
if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED)) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("%s: Updating peer (%s) status with NHT", __FUNCTION__, peer->host);
zlog_debug("%s: Updating peer (%s) status with NHT",
__FUNCTION__, peer->host);
bgp_fsm_nht_update(peer, bgp_isvalid_nexthop(bnc));
SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
}
@ -752,17 +721,15 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
* make - if set, make the association. if unset, just break the existing
* association.
*/
static void
path_nh_map (struct bgp_info *path, struct bgp_nexthop_cache *bnc, int make)
{
if (path->nexthop)
static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
int make)
{
if (path->nexthop) {
LIST_REMOVE(path, nh_thread);
path->nexthop->path_count--;
path->nexthop = NULL;
}
if (make)
{
if (make) {
LIST_INSERT_HEAD(&(bnc->paths), path, nh_thread);
path->nexthop = bnc;
path->nexthop->path_count++;

View File

@ -45,8 +45,8 @@ extern int bgp_find_nexthop(struct bgp_info *p, int connected);
* peer - The BGP peer associated with this NHT
* connected - True if NH MUST be a connected route
*/
extern int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t a,
struct bgp_info *p, struct peer *peer, int connected);
extern int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t a, struct bgp_info *p,
struct peer *peer, int connected);
/**
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.

File diff suppressed because it is too large Load Diff

View File

@ -22,34 +22,29 @@
#define _QUAGGA_BGP_OPEN_H
/* Standard header for capability TLV */
struct capability_header
{
struct capability_header {
u_char code;
u_char length;
};
/* Generic MP capability data */
struct capability_mp_data
{
struct capability_mp_data {
iana_afi_t afi;
u_char reserved;
safi_t safi;
};
struct capability_as4
{
struct capability_as4 {
uint32_t as4;
};
struct graceful_restart_af
{
struct graceful_restart_af {
afi_t afi;
safi_t safi;
u_char flag;
};
struct capability_gr
{
struct capability_gr {
u_int16_t restart_flag_time;
struct graceful_restart_af gr[];
};
@ -68,7 +63,6 @@ struct capability_gr
#define CAPABILITY_CODE_REFRESH_OLD 128 /* Route Refresh Capability(cisco) */
#define CAPABILITY_CODE_ORF_OLD 130 /* Cooperative Route Filtering Capability(cisco) */
/* Capability Length */
#define CAPABILITY_CODE_MP_LEN 4
#define CAPABILITY_CODE_REFRESH_LEN 0
@ -101,7 +95,8 @@ struct capability_gr
extern int bgp_open_option_parse(struct peer *, u_char, int *);
extern void bgp_open_capability(struct stream *, struct peer *);
extern void bgp_capability_vty_out (struct vty *, struct peer *, u_char, json_object *);
extern void bgp_capability_vty_out(struct vty *, struct peer *, u_char,
json_object *);
extern as_t peek_for_as4_capability(struct peer *, u_char);
#endif /* _QUAGGA_BGP_OPEN_H */

File diff suppressed because it is too large Load Diff

View File

@ -47,15 +47,17 @@ extern void bgp_open_send (struct peer *);
extern void bgp_notify_send(struct peer *, u_int8_t, u_int8_t);
extern void bgp_notify_send_with_data(struct peer *, u_int8_t, u_int8_t,
u_int8_t *, size_t);
extern void bgp_route_refresh_send (struct peer *, afi_t, safi_t, u_char, u_char, int);
extern void bgp_route_refresh_send(struct peer *, afi_t, safi_t, u_char, u_char,
int);
extern void bgp_capability_send(struct peer *, afi_t, safi_t, int, int);
extern void bgp_default_update_send (struct peer *, struct attr *,
afi_t, safi_t, struct peer *);
extern void bgp_default_update_send(struct peer *, struct attr *, afi_t, safi_t,
struct peer *);
extern void bgp_default_withdraw_send(struct peer *, afi_t, safi_t);
extern int bgp_capability_receive(struct peer *, bgp_size_t);
extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *, int mp_withdraw);
extern int bgp_nlri_parse(struct peer *, struct attr *, struct bgp_nlri *,
int mp_withdraw);
extern void bgp_update_restarted_peers(struct peer *);
extern void bgp_update_implicit_eors(struct peer *);

209
bgpd/bgp_rd.c Normal file
View File

@ -0,0 +1,209 @@
/* BGP RD definitions for BGP-based VPNs (IP/EVPN)
* -- brought over from bgpd/bgp_mplsvpn.c
* Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
*
* This file is part of FRR.
*
* FRR is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* FRR is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRR; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include "command.h"
#include "log.h"
#include "prefix.h"
#include "memory.h"
#include "stream.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_rd.h"
#include "bgpd/bgp_attr.h"
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
#endif
u_int16_t decode_rd_type(u_char *pnt)
{
u_int16_t v;
v = ((u_int16_t)*pnt++ << 8);
#if ENABLE_BGP_VNC
/*
* VNC L2 stores LHI in lower byte, so omit it
*/
if (v != RD_TYPE_VNC_ETH)
v |= (u_int16_t)*pnt;
#else /* duplicate code for clarity */
v |= (u_int16_t)*pnt;
#endif
return v;
}
void encode_rd_type(u_int16_t v, u_char *pnt)
{
*((u_int16_t *)pnt) = htons(v);
}
/* type == RD_TYPE_AS */
void decode_rd_as(u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int16_t)*pnt++ << 8;
rd_as->as |= (u_int16_t)*pnt++;
rd_as->val = ((u_int32_t)*pnt++ << 24);
rd_as->val |= ((u_int32_t)*pnt++ << 16);
rd_as->val |= ((u_int32_t)*pnt++ << 8);
rd_as->val |= (u_int32_t)*pnt;
}
/* type == RD_TYPE_AS4 */
void decode_rd_as4(u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int32_t)*pnt++ << 24;
rd_as->as |= (u_int32_t)*pnt++ << 16;
rd_as->as |= (u_int32_t)*pnt++ << 8;
rd_as->as |= (u_int32_t)*pnt++;
rd_as->val = ((u_int16_t)*pnt++ << 8);
rd_as->val |= (u_int16_t)*pnt;
}
/* type == RD_TYPE_IP */
void decode_rd_ip(u_char *pnt, struct rd_ip *rd_ip)
{
memcpy(&rd_ip->ip, pnt, 4);
pnt += 4;
rd_ip->val = ((u_int16_t)*pnt++ << 8);
rd_ip->val |= (u_int16_t)*pnt;
}
#if ENABLE_BGP_VNC
/* type == RD_TYPE_VNC_ETH */
void decode_rd_vnc_eth(u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
{
rd_vnc_eth->type = RD_TYPE_VNC_ETH;
rd_vnc_eth->local_nve_id = pnt[1];
memcpy(rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
}
#endif
int str2prefix_rd(const char *str, struct prefix_rd *prd)
{
int ret; /* ret of called functions */
int lret; /* local ret, of this func */
char *p;
char *p2;
struct stream *s = NULL;
char *half = NULL;
struct in_addr addr;
s = stream_new(8);
prd->family = AF_UNSPEC;
prd->prefixlen = 64;
lret = 0;
p = strchr(str, ':');
if (!p)
goto out;
if (!all_digit(p + 1))
goto out;
half = XMALLOC(MTYPE_TMP, (p - str) + 1);
memcpy(half, str, (p - str));
half[p - str] = '\0';
p2 = strchr(str, '.');
if (!p2) {
unsigned long as_val;
if (!all_digit(half))
goto out;
as_val = atol(half);
if (as_val > 0xffff) {
stream_putw(s, RD_TYPE_AS4);
stream_putl(s, as_val);
stream_putw(s, atol(p + 1));
} else {
stream_putw(s, RD_TYPE_AS);
stream_putw(s, as_val);
stream_putl(s, atol(p + 1));
}
} else {
ret = inet_aton(half, &addr);
if (!ret)
goto out;
stream_putw(s, RD_TYPE_IP);
stream_put_in_addr(s, &addr);
stream_putw(s, atol(p + 1));
}
memcpy(prd->val, s->data, 8);
lret = 1;
out:
if (s)
stream_free(s);
if (half)
XFREE(MTYPE_TMP, half);
return lret;
}
char *prefix_rd2str(struct prefix_rd *prd, char *buf, size_t size)
{
u_char *pnt;
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip;
if (size < RD_ADDRSTRLEN)
return NULL;
pnt = prd->val;
type = decode_rd_type(pnt);
if (type == RD_TYPE_AS) {
decode_rd_as(pnt + 2, &rd_as);
snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
return buf;
} else if (type == RD_TYPE_AS4) {
decode_rd_as4(pnt + 2, &rd_as);
snprintf(buf, size, "%u:%d", rd_as.as, rd_as.val);
return buf;
} else if (type == RD_TYPE_IP) {
decode_rd_ip(pnt + 2, &rd_ip);
snprintf(buf, size, "%s:%d", inet_ntoa(rd_ip.ip), rd_ip.val);
return buf;
}
#if ENABLE_BGP_VNC
else if (type == RD_TYPE_VNC_ETH) {
snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
*(pnt + 1), /* LHI */
*(pnt + 2), /* MAC[0] */
*(pnt + 3), *(pnt + 4), *(pnt + 5), *(pnt + 6),
*(pnt + 7));
return buf;
}
#endif
return NULL;
}

70
bgpd/bgp_rd.h Normal file
View File

@ -0,0 +1,70 @@
/* BGP RD definitions for BGP-based VPNs (IP/EVPN)
* -- brought over from bgpd/bgp_mplsvpn.h
* Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
*
* This file is part of FRR.
*
* FRR is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* FRR is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FRR; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _QUAGGA_BGP_RD_H
#define _QUAGGA_BGP_RD_H
/* RD types */
#define RD_TYPE_AS 0
#define RD_TYPE_IP 1
#define RD_TYPE_AS4 2
#if ENABLE_BGP_VNC
#define RD_TYPE_VNC_ETH 0xff00 /* VNC L2VPN */
#endif
#define RD_ADDRSTRLEN 28
struct rd_as {
u_int16_t type;
as_t as;
u_int32_t val;
};
struct rd_ip {
u_int16_t type;
struct in_addr ip;
u_int16_t val;
};
#if ENABLE_BGP_VNC
struct rd_vnc_eth {
u_int16_t type;
uint8_t local_nve_id;
struct ethaddr macaddr;
};
#endif
extern u_int16_t decode_rd_type(u_char *pnt);
extern void encode_rd_type(u_int16_t, u_char *);
extern void decode_rd_as(u_char *pnt, struct rd_as *rd_as);
extern void decode_rd_as4(u_char *pnt, struct rd_as *rd_as);
extern void decode_rd_ip(u_char *pnt, struct rd_ip *rd_ip);
#if ENABLE_BGP_VNC
extern void decode_rd_vnc_eth(u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
#endif
extern int str2prefix_rd(const char *, struct prefix_rd *);
extern char *prefix_rd2str(struct prefix_rd *, char *, size_t);
#endif /* _QUAGGA_BGP_RD_H */

View File

@ -35,8 +35,7 @@
(^|[,{}() ]|$) */
regex_t *
bgp_regcomp (const char *regstr)
regex_t *bgp_regcomp(const char *regstr)
{
/* Convert _ character to generic regular expression. */
int i, j;
@ -54,14 +53,12 @@ bgp_regcomp (const char *regstr)
magic_str = XMALLOC(MTYPE_TMP, len + (14 * magic) + 1);
for (i = 0, j = 0; i < len; i++)
{
if (regstr[i] == '_')
{
memcpy (magic_str + j, magic_regexp, strlen (magic_regexp));
for (i = 0, j = 0; i < len; i++) {
if (regstr[i] == '_') {
memcpy(magic_str + j, magic_regexp,
strlen(magic_regexp));
j += strlen(magic_regexp);
}
else
} else
magic_str[j++] = regstr[i];
}
magic_str[j] = '\0';
@ -72,8 +69,7 @@ bgp_regcomp (const char *regstr)
XFREE(MTYPE_TMP, magic_str);
if (ret != 0)
{
if (ret != 0) {
XFREE(MTYPE_BGP_REGEXP, regex);
return NULL;
}
@ -81,14 +77,12 @@ bgp_regcomp (const char *regstr)
return regex;
}
int
bgp_regexec (regex_t *regex, struct aspath *aspath)
int bgp_regexec(regex_t *regex, struct aspath *aspath)
{
return regexec(regex, aspath->str, 0, NULL, 0);
}
void
bgp_regex_free (regex_t *regex)
void bgp_regex_free(regex_t *regex)
{
regfree(regex);
XFREE(MTYPE_BGP_REGEXP, regex);

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,7 @@
struct bgp_nexthop_cache;
struct bgp_route_evpn;
enum bgp_show_type
{
enum bgp_show_type {
bgp_show_type_normal,
bgp_show_type_regexp,
bgp_show_type_prefix_list,
@ -52,18 +51,18 @@ enum bgp_show_type
};
#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, "\
"h history, * valid, > best, = multipath,%s"\
" i internal, r RIB-failure, S Stale, R Removed"
#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s"
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path"
#define BGP_SHOW_SCODE_HEADER \
"Status codes: s suppressed, d damped, " \
"h history, * valid, > best, = multipath,\n" \
" i internal, r RIB-failure, S Stale, R Removed\n"
#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n"
/* Ancillary information to struct bgp_info,
* used for uncommonly used data (aggregation, MPLS, etc.)
* and lazily allocated to save memory.
*/
struct bgp_info_extra
{
struct bgp_info_extra {
/* Pointer to dampening structure. */
struct bgp_damp_info *damp_info;
@ -74,35 +73,45 @@ struct bgp_info_extra
u_int32_t igpmetric;
/* MPLS label. */
u_char tag[3];
mpls_label_t label;
#if ENABLE_BGP_VNC
union {
struct {
void *rfapi_handle; /* export: NVE advertising this route */
struct list *local_nexthops; /* optional, for static routes */
void *rfapi_handle; /* export: NVE advertising this
route */
struct list *local_nexthops; /* optional, for static
routes */
} export;
struct {
struct thread *timer;
void *hme; /* encap monitor, if this is a VPN route */
struct prefix_rd rd; /* import: route's route-distinguisher */
u_char un_family; /* family of cached un address, 0 if unset */
struct prefix_rd
rd; /* import: route's route-distinguisher */
u_char un_family; /* family of cached un address, 0 if
unset */
union {
struct in_addr addr4;
struct in6_addr addr6;
} un; /* cached un address */
time_t create_time;
struct prefix aux_prefix; /* AFI_L2VPN: the IP addr, if family set */
struct
prefix
aux_prefix; /* AFI_L2VPN: the IP addr,
if family set */
} import;
} vnc;
#endif
/* For imported routes into a VNI (or VRF), this points to the parent.
*/
void *parent;
};
struct bgp_info
{
struct bgp_info {
/* For linked list. */
struct bgp_info *next;
struct bgp_info *prev;
@ -171,12 +180,16 @@ struct bgp_info
/* Addpath identifiers */
u_int32_t addpath_rx_id;
u_int32_t addpath_tx_id;
};
/* Structure used in BGP path selection */
struct bgp_info_pair {
struct bgp_info *old;
struct bgp_info *new;
};
/* BGP static route configuration. */
struct bgp_static
{
struct bgp_static {
/* Backdoor configuration. */
int backdoor;
@ -197,8 +210,7 @@ struct bgp_static
u_int32_t atomic;
/* BGP redistribute route-map. */
struct
{
struct {
char *name;
struct route_map *map;
} rmap;
@ -207,7 +219,7 @@ struct bgp_static
struct prefix_rd prd;
/* MPLS label. */
u_char tag[3];
mpls_label_t label;
/* EVPN */
struct eth_segment_id *eth_s_id;
@ -217,13 +229,13 @@ struct bgp_static
};
#define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \
((nhlen) < IPV4_MAX_BYTELEN ? 0 : \
((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))
((nhlen) < IPV4_MAX_BYTELEN \
? 0 \
: ((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))
#define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
(! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP)) && \
(attr)->extra && ((attr)->extra->mp_nexthop_len == 16 || \
(attr)->extra->mp_nexthop_len == 32))
(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) \
&& ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
#define BGP_INFO_COUNTABLE(BI) \
(!CHECK_FLAG((BI)->flags, BGP_INFO_HISTORY) \
&& !CHECK_FLAG((BI)->flags, BGP_INFO_REMOVED))
@ -265,25 +277,17 @@ struct bgp_static
/* path PREFIX (addpath rxid NUMBER) */
#define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32
enum bgp_path_type
{
BGP_PATH_ALL,
BGP_PATH_BESTPATH,
BGP_PATH_MULTIPATH
};
enum bgp_path_type { BGP_PATH_ALL, BGP_PATH_BESTPATH, BGP_PATH_MULTIPATH };
static inline void
bgp_bump_version (struct bgp_node *node)
static inline void bgp_bump_version(struct bgp_node *node)
{
node->version = bgp_table_next_version(bgp_node_table(node));
}
static inline int
bgp_fibupd_safi (safi_t safi)
static inline int bgp_fibupd_safi(safi_t safi)
{
if (safi == SAFI_UNICAST ||
safi == SAFI_MULTICAST ||
safi == SAFI_LABELED_UNICAST)
if (safi == SAFI_UNICAST || safi == SAFI_MULTICAST
|| safi == SAFI_LABELED_UNICAST)
return 1;
return 0;
}
@ -309,44 +313,50 @@ extern struct bgp_node *bgp_afi_node_get (struct bgp_table *table, afi_t afi,
extern struct bgp_info *bgp_info_lock(struct bgp_info *);
extern struct bgp_info *bgp_info_unlock(struct bgp_info *);
extern void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri);
extern struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *);
extern void bgp_info_set_flag(struct bgp_node *, struct bgp_info *, u_int32_t);
extern void bgp_info_unset_flag (struct bgp_node *, struct bgp_info *, u_int32_t);
extern void bgp_info_unset_flag(struct bgp_node *, struct bgp_info *,
u_int32_t);
extern void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, char *buf);
extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *);
extern int bgp_maximum_prefix_overflow(struct peer *, afi_t, safi_t, int);
extern void bgp_redistribute_add (struct bgp *, struct prefix *, const struct in_addr *,
extern void bgp_redistribute_add(struct bgp *, struct prefix *,
const struct in_addr *,
const struct in6_addr *, unsigned int ifindex,
u_int32_t, u_char, u_short, route_tag_t);
extern void bgp_redistribute_delete (struct bgp *, struct prefix *, u_char, u_short);
extern void bgp_redistribute_delete(struct bgp *, struct prefix *, u_char,
u_short);
extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, u_short);
extern void bgp_static_add(struct bgp *);
extern void bgp_static_delete(struct bgp *);
extern void bgp_static_redo_import_check(struct bgp *);
extern void bgp_purge_static_redist_routes(struct bgp *bgp);
extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,
afi_t, safi_t);
extern void bgp_static_update(struct bgp *, struct prefix *,
struct bgp_static *, afi_t, safi_t);
extern void bgp_static_withdraw(struct bgp *, struct prefix *, afi_t, safi_t);
extern int bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *,
extern int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
const char *, const char *, const char *,
int, const char *, const char *, const char *, const char *);
const char *, int, const char *, const char *,
const char *, const char *);
extern int bgp_static_unset_safi (afi_t afi, safi_t safi, struct vty *, const char *,
const char *, const char *,
int, const char *, const char *, const char *);
extern int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *,
const char *, const char *, const char *, int,
const char *, const char *, const char *);
/* this is primarily for MPLS-VPN */
extern int bgp_update(struct peer *, struct prefix *, u_int32_t, struct attr *,
afi_t, safi_t, int, int, struct prefix_rd *,
u_char *, int, struct bgp_route_evpn *);
extern int bgp_withdraw (struct peer *, struct prefix *, u_int32_t, struct attr *,
afi_t, safi_t, int, int, struct prefix_rd *, u_char *,
mpls_label_t *, int, struct bgp_route_evpn *);
extern int bgp_withdraw(struct peer *, struct prefix *, u_int32_t,
struct attr *, afi_t, safi_t, int, int,
struct prefix_rd *, mpls_label_t *,
struct bgp_route_evpn *);
/* for bgp_nexthop and bgp_damp */
@ -359,28 +369,37 @@ extern void bgp_process (struct bgp *, struct bgp_node *, afi_t, safi_t);
extern void bgp_add_eoiu_mark(struct bgp *);
extern int bgp_config_write_table_map(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern int bgp_config_write_network (struct vty *, struct bgp *, afi_t, safi_t, int *);
extern int bgp_config_write_distance (struct vty *, struct bgp *, afi_t, safi_t, int *);
extern int bgp_config_write_network(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern int bgp_config_write_distance(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern void bgp_aggregate_increment (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
extern void bgp_aggregate_decrement (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
struct bgp_info *, afi_t, safi_t);
extern void bgp_aggregate_decrement(struct bgp *, struct prefix *,
struct bgp_info *, afi_t, safi_t);
extern u_char bgp_distance_apply (struct prefix *, struct bgp_info *, afi_t, safi_t, struct bgp *);
extern u_char bgp_distance_apply(struct prefix *, struct bgp_info *, afi_t,
safi_t, struct bgp *);
extern afi_t bgp_node_afi(struct vty *);
extern safi_t bgp_node_safi(struct vty *);
extern void route_vty_out (struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *);
extern void route_vty_out_tag (struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *);
extern void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t, u_char, json_object *);
extern void
route_vty_out_overlay (struct vty *vty, struct prefix *p,
struct bgp_info *binfo, int display, json_object *json);
extern struct bgp_info *info_make(int type, int sub_type, u_short instance,
struct peer *peer, struct attr *attr,
struct bgp_node *rn);
extern int
subgroup_process_announce_selected (struct update_subgroup *subgrp,
extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int,
safi_t, json_object *);
extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *,
int, safi_t, json_object *);
extern void route_vty_out_tmp(struct vty *, struct prefix *, struct attr *,
safi_t, u_char, json_object *);
extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
struct bgp_info *binfo, int display,
json_object *json);
extern int subgroup_process_announce_selected(struct update_subgroup *subgrp,
struct bgp_info *selected,
struct bgp_node *rn,
u_int32_t addpath_tx_id);
@ -393,13 +412,32 @@ extern void bgp_peer_clear_node_queue_drain_immediate (struct peer *peer);
extern void bgp_process_queues_drain_immediate(void);
/* for encap/vpn */
extern struct bgp_node *
bgp_afi_node_get (struct bgp_table *, afi_t , safi_t , struct prefix *,
struct prefix_rd *);
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *, afi_t, safi_t,
struct prefix *, struct prefix_rd *);
extern struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
safi_t safi, struct prefix *p,
struct prefix_rd *prd);
extern struct bgp_info *bgp_info_new(void);
extern void bgp_info_restore(struct bgp_node *, struct bgp_info *);
extern int bgp_info_cmp_compatible(struct bgp *, struct bgp_info *,
struct bgp_info *, afi_t, safi_t );
struct bgp_info *, char *pfx_buf, afi_t afi,
safi_t safi);
extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
struct bgp_maxpaths_cfg *mpath_cfg,
struct bgp_info_pair *result, afi_t afi,
safi_t safi);
extern void bgp_zebra_clear_route_change_flags(struct bgp_node *rn);
extern int bgp_zebra_has_route_changed(struct bgp_node *rn,
struct bgp_info *selected);
extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
struct bgp_node *rn,
struct prefix_rd *prd, afi_t afi,
safi_t safi, json_object *json);
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct prefix *p, struct bgp_info *binfo,
afi_t afi, safi_t safi,
json_object *json_paths);
#endif /* _QUAGGA_BGP_ROUTE_H */

File diff suppressed because it is too large Load Diff

View File

@ -125,126 +125,199 @@ static oid bgp_trap_oid [] = { BGP4MIB, 0 };
static struct in_addr bgp_empty_addr = {.s_addr = 0};
/* Hook functions. */
static u_char *bgpVersion (struct variable *, oid [], size_t *, int,
static u_char *bgpVersion(struct variable *, oid[], size_t *, int, size_t *,
WriteMethod **);
static u_char *bgpLocalAs(struct variable *, oid[], size_t *, int, size_t *,
WriteMethod **);
static u_char *bgpPeerTable(struct variable *, oid[], size_t *, int, size_t *,
WriteMethod **);
static u_char *bgpRcvdPathAttrTable(struct variable *, oid[], size_t *, int,
size_t *, WriteMethod **);
static u_char *bgpIdentifier(struct variable *, oid[], size_t *, int, size_t *,
WriteMethod **);
static u_char *bgp4PathAttrTable(struct variable *, oid[], size_t *, int,
size_t *, WriteMethod **);
static u_char *bgpLocalAs (struct variable *, oid [], size_t *,
int, size_t *, WriteMethod **);
static u_char *bgpPeerTable (struct variable *, oid [], size_t *,
int, size_t *, WriteMethod **);
static u_char *bgpRcvdPathAttrTable (struct variable *, oid [], size_t *,
int, size_t *, WriteMethod **);
static u_char *bgpIdentifier (struct variable *, oid [], size_t *,
int, size_t *, WriteMethod **);
static u_char *bgp4PathAttrTable (struct variable *, oid [], size_t *,
int, size_t *, WriteMethod **);
/* static u_char *bgpTraps (); */
static struct variable bgp_variables[] =
{
static struct variable bgp_variables[] = {
/* BGP version. */
{BGPVERSION, OCTET_STRING, RONLY, bgpVersion,
1, {1}},
{BGPVERSION, OCTET_STRING, RONLY, bgpVersion, 1, {1}},
/* BGP local AS. */
{BGPLOCALAS, INTEGER, RONLY, bgpLocalAs,
1, {2}},
{BGPLOCALAS, INTEGER, RONLY, bgpLocalAs, 1, {2}},
/* BGP peer table. */
{BGPPEERIDENTIFIER, IPADDRESS, RONLY, bgpPeerTable,
3, {3, 1, 1}},
{BGPPEERSTATE, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 2}},
{BGPPEERADMINSTATUS, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 3}},
{BGPPEERNEGOTIATEDVERSION, INTEGER32, RONLY, bgpPeerTable,
3, {3, 1, 4}},
{BGPPEERLOCALADDR, IPADDRESS, RONLY, bgpPeerTable,
3, {3, 1, 5}},
{BGPPEERLOCALPORT, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 6}},
{BGPPEERREMOTEADDR, IPADDRESS, RONLY, bgpPeerTable,
3, {3, 1, 7}},
{BGPPEERREMOTEPORT, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 8}},
{BGPPEERREMOTEAS, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 9}},
{BGPPEERINUPDATES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 10}},
{BGPPEEROUTUPDATES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 11}},
{BGPPEERINTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 12}},
{BGPPEEROUTTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 13}},
{BGPPEERLASTERROR, OCTET_STRING, RONLY, bgpPeerTable,
3, {3, 1, 14}},
{BGPPEERFSMESTABLISHEDTRANSITIONS, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 15}},
{BGPPEERFSMESTABLISHEDTIME, GAUGE32, RONLY, bgpPeerTable,
3, {3, 1, 16}},
{BGPPEERCONNECTRETRYINTERVAL, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 17}},
{BGPPEERHOLDTIME, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 18}},
{BGPPEERKEEPALIVE, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 19}},
{BGPPEERHOLDTIMECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 20}},
{BGPPEERKEEPALIVECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 21}},
{BGPPEERMINROUTEADVERTISEMENTINTERVAL, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 23}},
{BGPPEERINUPDATEELAPSEDTIME, GAUGE32, RONLY, bgpPeerTable,
3, {3, 1, 24}},
{BGPPEERIDENTIFIER, IPADDRESS, RONLY, bgpPeerTable, 3, {3, 1, 1}},
{BGPPEERSTATE, INTEGER, RONLY, bgpPeerTable, 3, {3, 1, 2}},
{BGPPEERADMINSTATUS, INTEGER, RWRITE, bgpPeerTable, 3, {3, 1, 3}},
{BGPPEERNEGOTIATEDVERSION,
INTEGER32,
RONLY,
bgpPeerTable,
3,
{3, 1, 4}},
{BGPPEERLOCALADDR, IPADDRESS, RONLY, bgpPeerTable, 3, {3, 1, 5}},
{BGPPEERLOCALPORT, INTEGER, RONLY, bgpPeerTable, 3, {3, 1, 6}},
{BGPPEERREMOTEADDR, IPADDRESS, RONLY, bgpPeerTable, 3, {3, 1, 7}},
{BGPPEERREMOTEPORT, INTEGER, RONLY, bgpPeerTable, 3, {3, 1, 8}},
{BGPPEERREMOTEAS, INTEGER, RONLY, bgpPeerTable, 3, {3, 1, 9}},
{BGPPEERINUPDATES, COUNTER32, RONLY, bgpPeerTable, 3, {3, 1, 10}},
{BGPPEEROUTUPDATES, COUNTER32, RONLY, bgpPeerTable, 3, {3, 1, 11}},
{BGPPEERINTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable, 3, {3, 1, 12}},
{BGPPEEROUTTOTALMESSAGES,
COUNTER32,
RONLY,
bgpPeerTable,
3,
{3, 1, 13}},
{BGPPEERLASTERROR, OCTET_STRING, RONLY, bgpPeerTable, 3, {3, 1, 14}},
{BGPPEERFSMESTABLISHEDTRANSITIONS,
COUNTER32,
RONLY,
bgpPeerTable,
3,
{3, 1, 15}},
{BGPPEERFSMESTABLISHEDTIME,
GAUGE32,
RONLY,
bgpPeerTable,
3,
{3, 1, 16}},
{BGPPEERCONNECTRETRYINTERVAL,
INTEGER,
RWRITE,
bgpPeerTable,
3,
{3, 1, 17}},
{BGPPEERHOLDTIME, INTEGER, RONLY, bgpPeerTable, 3, {3, 1, 18}},
{BGPPEERKEEPALIVE, INTEGER, RONLY, bgpPeerTable, 3, {3, 1, 19}},
{BGPPEERHOLDTIMECONFIGURED,
INTEGER,
RWRITE,
bgpPeerTable,
3,
{3, 1, 20}},
{BGPPEERKEEPALIVECONFIGURED,
INTEGER,
RWRITE,
bgpPeerTable,
3,
{3, 1, 21}},
{BGPPEERMINROUTEADVERTISEMENTINTERVAL,
INTEGER,
RWRITE,
bgpPeerTable,
3,
{3, 1, 23}},
{BGPPEERINUPDATEELAPSEDTIME,
GAUGE32,
RONLY,
bgpPeerTable,
3,
{3, 1, 24}},
/* BGP identifier. */
{BGPIDENTIFIER, IPADDRESS, RONLY, bgpIdentifier,
1, {4}},
{BGPIDENTIFIER, IPADDRESS, RONLY, bgpIdentifier, 1, {4}},
/* BGP received path attribute table. */
{BGPPATHATTRPEER, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 1}},
{BGPPATHATTRDESTNETWORK, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 2}},
{BGPPATHATTRORIGIN, INTEGER, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 3}},
{BGPPATHATTRASPATH, OCTET_STRING, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 4}},
{BGPPATHATTRNEXTHOP, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 5}},
{BGPPATHATTRINTERASMETRIC, INTEGER32, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 6}},
{BGPPATHATTRPEER, IPADDRESS, RONLY, bgpRcvdPathAttrTable, 3, {5, 1, 1}},
{BGPPATHATTRDESTNETWORK,
IPADDRESS,
RONLY,
bgpRcvdPathAttrTable,
3,
{5, 1, 2}},
{BGPPATHATTRORIGIN, INTEGER, RONLY, bgpRcvdPathAttrTable, 3, {5, 1, 3}},
{BGPPATHATTRASPATH,
OCTET_STRING,
RONLY,
bgpRcvdPathAttrTable,
3,
{5, 1, 4}},
{BGPPATHATTRNEXTHOP,
IPADDRESS,
RONLY,
bgpRcvdPathAttrTable,
3,
{5, 1, 5}},
{BGPPATHATTRINTERASMETRIC,
INTEGER32,
RONLY,
bgpRcvdPathAttrTable,
3,
{5, 1, 6}},
/* BGP-4 received path attribute table. */
{BGP4PATHATTRPEER, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 1}},
{BGP4PATHATTRIPADDRPREFIXLEN, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 2}},
{BGP4PATHATTRIPADDRPREFIX, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 3}},
{BGP4PATHATTRORIGIN, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 4}},
{BGP4PATHATTRASPATHSEGMENT, OCTET_STRING, RONLY, bgp4PathAttrTable,
3, {6, 1, 5}},
{BGP4PATHATTRNEXTHOP, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 6}},
{BGP4PATHATTRMULTIEXITDISC, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 7}},
{BGP4PATHATTRLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 8}},
{BGP4PATHATTRATOMICAGGREGATE, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 9}},
{BGP4PATHATTRAGGREGATORAS, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 10}},
{BGP4PATHATTRAGGREGATORADDR, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 11}},
{BGP4PATHATTRCALCLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 12}},
{BGP4PATHATTRBEST, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 13}},
{BGP4PATHATTRUNKNOWN, OCTET_STRING, RONLY, bgp4PathAttrTable,
3, {6, 1, 14}},
{BGP4PATHATTRPEER, IPADDRESS, RONLY, bgp4PathAttrTable, 3, {6, 1, 1}},
{BGP4PATHATTRIPADDRPREFIXLEN,
INTEGER,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 2}},
{BGP4PATHATTRIPADDRPREFIX,
IPADDRESS,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 3}},
{BGP4PATHATTRORIGIN, INTEGER, RONLY, bgp4PathAttrTable, 3, {6, 1, 4}},
{BGP4PATHATTRASPATHSEGMENT,
OCTET_STRING,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 5}},
{BGP4PATHATTRNEXTHOP,
IPADDRESS,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 6}},
{BGP4PATHATTRMULTIEXITDISC,
INTEGER,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 7}},
{BGP4PATHATTRLOCALPREF,
INTEGER,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 8}},
{BGP4PATHATTRATOMICAGGREGATE,
INTEGER,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 9}},
{BGP4PATHATTRAGGREGATORAS,
INTEGER,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 10}},
{BGP4PATHATTRAGGREGATORADDR,
IPADDRESS,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 11}},
{BGP4PATHATTRCALCLOCALPREF,
INTEGER,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 12}},
{BGP4PATHATTRBEST, INTEGER, RONLY, bgp4PathAttrTable, 3, {6, 1, 13}},
{BGP4PATHATTRUNKNOWN,
OCTET_STRING,
RONLY,
bgp4PathAttrTable,
3,
{6, 1, 14}},
};
static u_char *
bgpVersion (struct variable *v, oid name[], size_t *length, int exact,
size_t *var_len, WriteMethod **write_method)
static u_char *bgpVersion(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
static u_char version;
@ -260,9 +333,9 @@ bgpVersion (struct variable *v, oid name[], size_t *length, int exact,
return (u_char *)&version;
}
static u_char *
bgpLocalAs (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
static u_char *bgpLocalAs(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct bgp *bgp;
@ -278,8 +351,7 @@ bgpLocalAs (struct variable *v, oid name[], size_t *length,
return SNMP_INTEGER(bgp->as);
}
static struct peer *
peer_lookup_addr_ipv4 (struct in_addr *src)
static struct peer *peer_lookup_addr_ipv4(struct in_addr *src)
{
struct bgp *bgp;
struct peer *peer;
@ -291,11 +363,9 @@ peer_lookup_addr_ipv4 (struct in_addr *src)
if (!bgp)
return NULL;
for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
{
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
ret = inet_pton(AF_INET, peer->host, &addr);
if (ret > 0)
{
if (ret > 0) {
if (IPV4_ADDR_SAME(&addr, src))
return peer;
}
@ -303,8 +373,7 @@ peer_lookup_addr_ipv4 (struct in_addr *src)
return NULL;
}
static struct peer *
bgp_peer_lookup_next (struct in_addr *src)
static struct peer *bgp_peer_lookup_next(struct in_addr *src)
{
struct bgp *bgp;
struct peer *peer;
@ -319,15 +388,12 @@ bgp_peer_lookup_next (struct in_addr *src)
if (!bgp)
return NULL;
for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
{
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
ret = inet_pton(AF_INET, peer->host, &su.sin.sin_addr);
if (ret > 0)
{
if (ret > 0) {
p = &su.sin.sin_addr;
if (ntohl (p->s_addr) > ntohl (src->s_addr))
{
if (ntohl(p->s_addr) > ntohl(src->s_addr)) {
src->s_addr = p->s_addr;
return peer;
}
@ -339,16 +405,15 @@ bgp_peer_lookup_next (struct in_addr *src)
/* 1.3.6.1.2.1.15.3.1.x = 10 */
#define PEERTAB_NAMELEN 10
static struct peer *
bgpPeerTable_lookup (struct variable *v, oid name[], size_t *length,
struct in_addr *addr, int exact)
static struct peer *bgpPeerTable_lookup(struct variable *v, oid name[],
size_t *length, struct in_addr *addr,
int exact)
{
struct peer *peer = NULL;
size_t namelen = v ? v->namelen : PEERTAB_NAMELEN;
int len;
if (exact)
{
if (exact) {
/* Check the length. */
if (*length - namelen != sizeof(struct in_addr))
return NULL;
@ -357,11 +422,10 @@ bgpPeerTable_lookup (struct variable *v, oid name[], size_t *length,
peer = peer_lookup_addr_ipv4(addr);
return peer;
}
else
{
} else {
len = *length - namelen;
if (len > 4) len = 4;
if (len > 4)
len = 4;
oid2in_addr(name + namelen, len, addr);
@ -379,21 +443,18 @@ bgpPeerTable_lookup (struct variable *v, oid name[], size_t *length,
}
/* BGP write methods. */
static int
write_bgpPeerTable (int action, u_char *var_val,
u_char var_val_type, size_t var_val_len,
u_char *statP, oid *name, size_t length)
static int write_bgpPeerTable(int action, u_char *var_val, u_char var_val_type,
size_t var_val_len, u_char *statP, oid *name,
size_t length)
{
struct in_addr addr;
struct peer *peer;
long intval;
if (var_val_type != ASN_INTEGER)
{
if (var_val_type != ASN_INTEGER) {
return SNMP_ERR_WRONGTYPE;
}
if (var_val_len != sizeof (long))
{
if (var_val_len != sizeof(long)) {
return SNMP_ERR_WRONGLENGTH;
}
@ -408,11 +469,10 @@ write_bgpPeerTable (int action, u_char *var_val,
if (action != SNMP_MSG_INTERNAL_SET_COMMIT)
return SNMP_ERR_NOERROR;
zlog_info ("%s: SNMP write .%ld = %ld",
peer->host, (long)name[PEERTAB_NAMELEN - 1], intval);
zlog_info("%s: SNMP write .%ld = %ld", peer->host,
(long)name[PEERTAB_NAMELEN - 1], intval);
switch (name[PEERTAB_NAMELEN - 1])
{
switch (name[PEERTAB_NAMELEN - 1]) {
case BGPPEERADMINSTATUS:
#define BGP_PeerAdmin_stop 1
#define BGP_PeerAdmin_start 2
@ -446,9 +506,9 @@ write_bgpPeerTable (int action, u_char *var_val,
return SNMP_ERR_NOERROR;
}
static u_char *
bgpPeerTable (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
static u_char *bgpPeerTable(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
static struct in_addr addr;
struct peer *peer;
@ -462,8 +522,7 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length,
if (!peer)
return NULL;
switch (v->magic)
{
switch (v->magic) {
case BGPPEERIDENTIFIER:
return SNMP_IPADDRESS(peer->remote_id);
break;
@ -490,7 +549,8 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length,
break;
case BGPPEERLOCALPORT:
if (peer->su_local)
return SNMP_INTEGER (ntohs (peer->su_local->sin.sin_port));
return SNMP_INTEGER(
ntohs(peer->su_local->sin.sin_port));
else
return SNMP_INTEGER(0);
break;
@ -502,7 +562,8 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length,
break;
case BGPPEERREMOTEPORT:
if (peer->su_remote)
return SNMP_INTEGER (ntohs (peer->su_remote->sin.sin_port));
return SNMP_INTEGER(
ntohs(peer->su_remote->sin.sin_port));
else
return SNMP_INTEGER(0);
break;
@ -523,17 +584,16 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length,
case BGPPEEROUTTOTALMESSAGES:
return SNMP_INTEGER(peer->open_out + peer->update_out
+ peer->keepalive_out + peer->notify_out
+ peer->refresh_out + peer->dynamic_cap_out);
+ peer->refresh_out
+ peer->dynamic_cap_out);
break;
case BGPPEERLASTERROR:
{
case BGPPEERLASTERROR: {
static u_char lasterror[2];
lasterror[0] = peer->notify.code;
lasterror[1] = peer->notify.subcode;
*var_len = 2;
return (u_char *)&lasterror;
}
break;
} break;
case BGPPEERFSMESTABLISHEDTRANSITIONS:
return SNMP_INTEGER(peer->established);
break;
@ -584,9 +644,9 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length,
return NULL;
}
static u_char *
bgpIdentifier (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
static u_char *bgpIdentifier(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct bgp *bgp;
@ -601,9 +661,9 @@ bgpIdentifier (struct variable *v, oid name[], size_t *length,
return SNMP_IPADDRESS(bgp->router_id);
}
static u_char *
bgpRcvdPathAttrTable (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
static u_char *bgpRcvdPathAttrTable(struct variable *v, oid name[],
size_t *length, int exact, size_t *var_len,
WriteMethod **write_method)
{
/* Received Path Attribute Table. This table contains, one entry
per path to a network, path attributes received from all peers
@ -612,9 +672,9 @@ bgpRcvdPathAttrTable (struct variable *v, oid name[], size_t *length,
return NULL;
}
static struct bgp_info *
bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
struct bgp *bgp, struct prefix_ipv4 *addr, int exact)
static struct bgp_info *bgp4PathAttrLookup(struct variable *v, oid name[],
size_t *length, struct bgp *bgp,
struct prefix_ipv4 *addr, int exact)
{
oid *offset;
int offsetlen;
@ -627,11 +687,9 @@ bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
sockunion_init(&su);
#define BGP_PATHATTR_ENTRY_OFFSET \
(IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
#define BGP_PATHATTR_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
if (exact)
{
if (exact) {
if (*length - v->namelen != BGP_PATHATTR_ENTRY_OFFSET)
return NULL;
@ -651,25 +709,21 @@ bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
/* Lookup node. */
rn = bgp_node_lookup(bgp->rib[AFI_IP][SAFI_UNICAST],
(struct prefix *)addr);
if (rn)
{
if (rn) {
bgp_unlock_node(rn);
for (binfo = rn->info; binfo; binfo = binfo->next)
if (sockunion_same(&binfo->peer->su, &su))
return binfo;
}
}
else
{
} else {
offset = name + v->namelen;
offsetlen = *length - v->namelen;
len = offsetlen;
if (offsetlen == 0)
rn = bgp_table_top(bgp->rib[AFI_IP][SAFI_UNICAST]);
else
{
else {
if (len > IN_ADDR_SIZE)
len = IN_ADDR_SIZE;
@ -690,51 +744,52 @@ bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
offsetlen--;
}
if (offsetlen > 0)
{
if (offsetlen > 0) {
len = offsetlen;
if (len > IN_ADDR_SIZE)
len = IN_ADDR_SIZE;
oid2in_addr(offset, len, &paddr);
}
else
} else
paddr.s_addr = 0;
if (!rn)
return NULL;
do
{
do {
min = NULL;
for (binfo = rn->info; binfo; binfo = binfo->next)
{
for (binfo = rn->info; binfo; binfo = binfo->next) {
if (binfo->peer->su.sin.sin_family == AF_INET
&& ntohl(paddr.s_addr)
< ntohl (binfo->peer->su.sin.sin_addr.s_addr))
{
if (min)
{
if (ntohl (binfo->peer->su.sin.sin_addr.s_addr)
< ntohl (min->peer->su.sin.sin_addr.s_addr))
< ntohl(binfo->peer->su.sin
.sin_addr
.s_addr)) {
if (min) {
if (ntohl(binfo->peer->su.sin
.sin_addr
.s_addr)
< ntohl(min->peer->su.sin
.sin_addr
.s_addr))
min = binfo;
}
else
} else
min = binfo;
}
}
if (min)
{
*length = v->namelen + BGP_PATHATTR_ENTRY_OFFSET;
if (min) {
*length =
v->namelen + BGP_PATHATTR_ENTRY_OFFSET;
offset = name + v->namelen;
oid_copy_addr (offset, &rn->p.u.prefix4, IN_ADDR_SIZE);
oid_copy_addr(offset, &rn->p.u.prefix4,
IN_ADDR_SIZE);
offset += IN_ADDR_SIZE;
*offset = rn->p.prefixlen;
offset++;
oid_copy_addr (offset, &min->peer->su.sin.sin_addr,
oid_copy_addr(offset,
&min->peer->su.sin.sin_addr,
IN_ADDR_SIZE);
addr->prefix = rn->p.u.prefix4;
addr->prefixlen = rn->p.prefixlen;
@ -745,15 +800,14 @@ bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
}
paddr.s_addr = 0;
}
while ((rn = bgp_route_next (rn)) != NULL);
} while ((rn = bgp_route_next(rn)) != NULL);
}
return NULL;
}
static u_char *
bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
static u_char *bgp4PathAttrTable(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
WriteMethod **write_method)
{
struct bgp *bgp;
struct bgp_info *binfo;
@ -772,8 +826,7 @@ bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
if (!binfo)
return NULL;
switch (v->magic)
{
switch (v->magic) {
case BGP4PATHATTRPEER: /* 1 */
return SNMP_IPADDRESS(binfo->peer->su.sin.sin_addr);
break;
@ -802,21 +855,17 @@ bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
return SNMP_INTEGER(1);
break;
case BGP4PATHATTRAGGREGATORAS: /* 10 */
if (binfo->attr->extra)
return SNMP_INTEGER (binfo->attr->extra->aggregator_as);
else
return SNMP_INTEGER (0);
return SNMP_INTEGER(binfo->attr->aggregator_as);
break;
case BGP4PATHATTRAGGREGATORADDR: /* 11 */
if (binfo->attr->extra)
return SNMP_IPADDRESS (binfo->attr->extra->aggregator_addr);
else
return SNMP_INTEGER (0);
return SNMP_IPADDRESS(binfo->attr->aggregator_addr);
break;
case BGP4PATHATTRCALCLOCALPREF: /* 12 */
return SNMP_INTEGER(-1);
break;
case BGP4PATHATTRBEST: /* 13 */
/* $FRR indent$ */
/* clang-format off */
#define BGP4_PathAttrBest_false 1
#define BGP4_PathAttrBest_true 2
if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
@ -833,14 +882,10 @@ bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
}
/* BGP Traps. */
static struct trap_object bgpTrapList[] =
{
{3, {3, 1, BGPPEERLASTERROR}},
{3, {3, 1, BGPPEERSTATE}}
};
static struct trap_object bgpTrapList[] = {{3, {3, 1, BGPPEERLASTERROR}},
{3, {3, 1, BGPPEERSTATE}}};
static int
bgpTrapEstablished (struct peer *peer)
static int bgpTrapEstablished(struct peer *peer)
{
int ret;
struct in_addr addr;
@ -853,16 +898,14 @@ bgpTrapEstablished (struct peer *peer)
oid_copy_addr(index, &addr, IN_ADDR_SIZE);
smux_trap(bgp_variables, sizeof bgp_variables / sizeof(struct variable),
bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid),
bgp_oid, sizeof bgp_oid / sizeof (oid),
index, IN_ADDR_SIZE,
bgp_trap_oid, sizeof bgp_trap_oid / sizeof(oid), bgp_oid,
sizeof bgp_oid / sizeof(oid), index, IN_ADDR_SIZE,
bgpTrapList, sizeof bgpTrapList / sizeof(struct trap_object),
BGPESTABLISHED);
return 0;
}
static int
bgpTrapBackwardTransition (struct peer *peer)
static int bgpTrapBackwardTransition(struct peer *peer)
{
int ret;
struct in_addr addr;
@ -875,24 +918,21 @@ bgpTrapBackwardTransition (struct peer *peer)
oid_copy_addr(index, &addr, IN_ADDR_SIZE);
smux_trap(bgp_variables, sizeof bgp_variables / sizeof(struct variable),
bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid),
bgp_oid, sizeof bgp_oid / sizeof (oid),
index, IN_ADDR_SIZE,
bgp_trap_oid, sizeof bgp_trap_oid / sizeof(oid), bgp_oid,
sizeof bgp_oid / sizeof(oid), index, IN_ADDR_SIZE,
bgpTrapList, sizeof bgpTrapList / sizeof(struct trap_object),
BGPBACKWARDTRANSITION);
return 0;
}
static int
bgp_snmp_init (struct thread_master *tm)
static int bgp_snmp_init(struct thread_master *tm)
{
smux_init(tm);
REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
return 0;
}
static int
bgp_snmp_module_init (void)
static int bgp_snmp_module_init(void)
{
hook_register(peer_established, bgpTrapEstablished);
hook_register(peer_backward_transition, bgpTrapBackwardTransition);
@ -900,9 +940,6 @@ bgp_snmp_module_init (void)
return 0;
}
FRR_MODULE_SETUP(
.name = "bgpd_snmp",
.version = FRR_VERSION,
FRR_MODULE_SETUP(.name = "bgpd_snmp", .version = FRR_VERSION,
.description = "bgpd AgentX SNMP module",
.init = bgp_snmp_module_init
)
.init = bgp_snmp_module_init)

View File

@ -30,20 +30,17 @@
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
void
bgp_table_lock (struct bgp_table *rt)
void bgp_table_lock(struct bgp_table *rt)
{
rt->lock++;
}
void
bgp_table_unlock (struct bgp_table *rt)
void bgp_table_unlock(struct bgp_table *rt)
{
assert(rt->lock > 0);
rt->lock--;
if (rt->lock != 0)
{
if (rt->lock != 0) {
return;
}
@ -53,11 +50,9 @@ bgp_table_unlock (struct bgp_table *rt)
XFREE(MTYPE_BGP_TABLE, rt);
}
void
bgp_table_finish (struct bgp_table **rt)
{
if (*rt != NULL)
void bgp_table_finish(struct bgp_table **rt)
{
if (*rt != NULL) {
bgp_table_unlock(*rt);
*rt = NULL;
}
@ -66,8 +61,8 @@ bgp_table_finish (struct bgp_table **rt)
/*
* bgp_node_create
*/
static struct route_node *
bgp_node_create (route_table_delegate_t *delegate, struct route_table *table)
static struct route_node *bgp_node_create(route_table_delegate_t *delegate,
struct route_table *table)
{
struct bgp_node *node;
node = XCALLOC(MTYPE_BGP_NODE, sizeof(struct bgp_node));
@ -77,8 +72,7 @@ bgp_node_create (route_table_delegate_t *delegate, struct route_table *table)
/*
* bgp_node_destroy
*/
static void
bgp_node_destroy (route_table_delegate_t *delegate,
static void bgp_node_destroy(route_table_delegate_t *delegate,
struct route_table *table, struct route_node *node)
{
struct bgp_node *bgp_node;
@ -90,16 +84,13 @@ bgp_node_destroy (route_table_delegate_t *delegate,
* Function vector to customize the behavior of the route table
* library for BGP route tables.
*/
route_table_delegate_t bgp_table_delegate = {
.create_node = bgp_node_create,
.destroy_node = bgp_node_destroy
};
route_table_delegate_t bgp_table_delegate = {.create_node = bgp_node_create,
.destroy_node = bgp_node_destroy};
/*
* bgp_table_init
*/
struct bgp_table *
bgp_table_init (afi_t afi, safi_t safi)
struct bgp_table *bgp_table_init(afi_t afi, safi_t safi)
{
struct bgp_table *rt;

View File

@ -21,10 +21,10 @@
#ifndef _QUAGGA_BGP_TABLE_H
#define _QUAGGA_BGP_TABLE_H
#include "mpls.h"
#include "table.h"
struct bgp_table
{
struct bgp_table {
/* afi/safi of this table */
afi_t afi;
safi_t safi;
@ -35,8 +35,7 @@ struct bgp_table
uint64_t version;
};
struct bgp_node
{
struct bgp_node {
/*
* CAUTION
*
@ -53,7 +52,7 @@ struct bgp_node
struct bgp_node *prn;
u_char local_label[3];
mpls_label_t local_label;
uint64_t version;
u_char flags;
@ -68,8 +67,7 @@ struct bgp_node
*
* Structure that holds state for iterating over a bgp table.
*/
typedef struct bgp_table_iter_t_
{
typedef struct bgp_table_iter_t_ {
struct bgp_table *table;
route_table_iter_t rt_iter;
} bgp_table_iter_t;
@ -85,8 +83,7 @@ extern void bgp_table_finish (struct bgp_table **);
*
* Returns the bgp_node structure corresponding to a route_node.
*/
static inline struct bgp_node *
bgp_node_from_rnode (struct route_node *rnode)
static inline struct bgp_node *bgp_node_from_rnode(struct route_node *rnode)
{
return (struct bgp_node *)rnode;
}
@ -96,8 +93,7 @@ bgp_node_from_rnode (struct route_node *rnode)
*
* Returns the route_node structure corresponding to a bgp_node.
*/
static inline struct route_node *
bgp_node_to_rnode (struct bgp_node *node)
static inline struct route_node *bgp_node_to_rnode(struct bgp_node *node)
{
return (struct route_node *)node;
}
@ -107,8 +103,7 @@ bgp_node_to_rnode (struct bgp_node *node)
*
* Returns the bgp_table that the given node is in.
*/
static inline struct bgp_table *
bgp_node_table (struct bgp_node *node)
static inline struct bgp_table *bgp_node_table(struct bgp_node *node)
{
return bgp_node_to_rnode(node)->table->info;
}
@ -118,8 +113,7 @@ bgp_node_table (struct bgp_node *node)
*
* Gets the parent node of the given node without locking it.
*/
static inline struct bgp_node *
bgp_node_parent_nolock (struct bgp_node *node)
static inline struct bgp_node *bgp_node_parent_nolock(struct bgp_node *node)
{
return bgp_node_from_rnode(node->parent);
}
@ -127,8 +121,7 @@ bgp_node_parent_nolock (struct bgp_node *node)
/*
* bgp_unlock_node
*/
static inline void
bgp_unlock_node (struct bgp_node *node)
static inline void bgp_unlock_node(struct bgp_node *node)
{
route_unlock_node(bgp_node_to_rnode(node));
}
@ -158,8 +151,7 @@ bgp_table_top (const struct bgp_table *const table)
/*
* bgp_route_next
*/
static inline struct bgp_node *
bgp_route_next (struct bgp_node *node)
static inline struct bgp_node *bgp_route_next(struct bgp_node *node)
{
return bgp_node_from_rnode(route_next(bgp_node_to_rnode(node)));
}
@ -167,8 +159,8 @@ bgp_route_next (struct bgp_node *node)
/*
* bgp_route_next_until
*/
static inline struct bgp_node *
bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit)
static inline struct bgp_node *bgp_route_next_until(struct bgp_node *node,
struct bgp_node *limit)
{
struct route_node *rnode;
@ -180,8 +172,8 @@ bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit)
/*
* bgp_node_get
*/
static inline struct bgp_node *
bgp_node_get (struct bgp_table *const table, struct prefix *p)
static inline struct bgp_node *bgp_node_get(struct bgp_table *const table,
struct prefix *p)
{
return bgp_node_from_rnode(route_node_get(table->route_table, p));
}
@ -198,8 +190,7 @@ bgp_node_lookup (const struct bgp_table *const table, struct prefix *p)
/*
* bgp_lock_node
*/
static inline struct bgp_node *
bgp_lock_node (struct bgp_node *node)
static inline struct bgp_node *bgp_lock_node(struct bgp_node *node)
{
return bgp_node_from_rnode(route_lock_node(bgp_node_to_rnode(node)));
}
@ -207,8 +198,8 @@ bgp_lock_node (struct bgp_node *node)
/*
* bgp_node_match
*/
static inline struct bgp_node *
bgp_node_match (const struct bgp_table *table, struct prefix *p)
static inline struct bgp_node *bgp_node_match(const struct bgp_table *table,
struct prefix *p)
{
return bgp_node_from_rnode(route_node_match(table->route_table, p));
}
@ -219,8 +210,8 @@ bgp_node_match (const struct bgp_table *table, struct prefix *p)
static inline struct bgp_node *
bgp_node_match_ipv4(const struct bgp_table *table, struct in_addr *addr)
{
return bgp_node_from_rnode (route_node_match_ipv4 (table->route_table,
addr));
return bgp_node_from_rnode(
route_node_match_ipv4(table->route_table, addr));
}
/*
@ -229,12 +220,11 @@ bgp_node_match_ipv4 (const struct bgp_table *table, struct in_addr *addr)
static inline struct bgp_node *
bgp_node_match_ipv6(const struct bgp_table *table, struct in6_addr *addr)
{
return bgp_node_from_rnode (route_node_match_ipv6 (table->route_table,
addr));
return bgp_node_from_rnode(
route_node_match_ipv6(table->route_table, addr));
}
static inline unsigned long
bgp_table_count (const struct bgp_table *const table)
static inline unsigned long bgp_table_count(const struct bgp_table *const table)
{
return route_table_count(table->route_table);
}
@ -242,8 +232,8 @@ bgp_table_count (const struct bgp_table *const table)
/*
* bgp_table_get_next
*/
static inline struct bgp_node *
bgp_table_get_next (const struct bgp_table *table, struct prefix *p)
static inline struct bgp_node *bgp_table_get_next(const struct bgp_table *table,
struct prefix *p)
{
return bgp_node_from_rnode(route_table_get_next(table->route_table, p));
}
@ -251,8 +241,8 @@ bgp_table_get_next (const struct bgp_table *table, struct prefix *p)
/*
* bgp_table_iter_init
*/
static inline void
bgp_table_iter_init (bgp_table_iter_t * iter, struct bgp_table *table)
static inline void bgp_table_iter_init(bgp_table_iter_t *iter,
struct bgp_table *table)
{
bgp_table_lock(table);
iter->table = table;
@ -262,8 +252,7 @@ bgp_table_iter_init (bgp_table_iter_t * iter, struct bgp_table *table)
/*
* bgp_table_iter_next
*/
static inline struct bgp_node *
bgp_table_iter_next (bgp_table_iter_t * iter)
static inline struct bgp_node *bgp_table_iter_next(bgp_table_iter_t *iter)
{
return bgp_node_from_rnode(route_table_iter_next(&iter->rt_iter));
}
@ -271,8 +260,7 @@ bgp_table_iter_next (bgp_table_iter_t * iter)
/*
* bgp_table_iter_cleanup
*/
static inline void
bgp_table_iter_cleanup (bgp_table_iter_t * iter)
static inline void bgp_table_iter_cleanup(bgp_table_iter_t *iter)
{
route_table_iter_cleanup(&iter->rt_iter);
bgp_table_unlock(iter->table);
@ -282,8 +270,7 @@ bgp_table_iter_cleanup (bgp_table_iter_t * iter)
/*
* bgp_table_iter_pause
*/
static inline void
bgp_table_iter_pause (bgp_table_iter_t * iter)
static inline void bgp_table_iter_pause(bgp_table_iter_t *iter)
{
route_table_iter_pause(&iter->rt_iter);
}
@ -291,8 +278,7 @@ bgp_table_iter_pause (bgp_table_iter_t * iter)
/*
* bgp_table_iter_is_done
*/
static inline int
bgp_table_iter_is_done (bgp_table_iter_t * iter)
static inline int bgp_table_iter_is_done(bgp_table_iter_t *iter)
{
return route_table_iter_is_done(&iter->rt_iter);
}
@ -300,22 +286,19 @@ bgp_table_iter_is_done (bgp_table_iter_t * iter)
/*
* bgp_table_iter_started
*/
static inline int
bgp_table_iter_started (bgp_table_iter_t * iter)
static inline int bgp_table_iter_started(bgp_table_iter_t *iter)
{
return route_table_iter_started(&iter->rt_iter);
}
/* This would benefit from a real atomic operation...
* until then. */
static inline uint64_t
bgp_table_next_version (struct bgp_table *table)
static inline uint64_t bgp_table_next_version(struct bgp_table *table)
{
return ++table->version;
}
static inline uint64_t
bgp_table_version (struct bgp_table *table)
static inline uint64_t bgp_table_version(struct bgp_table *table)
{
return table->version;
}

File diff suppressed because it is too large Load Diff

View File

@ -31,44 +31,32 @@
#define BGP_DEFAULT_SUBGROUP_COALESCE_TIME 200
#define PEER_UPDGRP_FLAGS (PEER_FLAG_LOCAL_AS_NO_PREPEND | \
PEER_FLAG_LOCAL_AS_REPLACE_AS)
#define PEER_UPDGRP_FLAGS \
(PEER_FLAG_LOCAL_AS_NO_PREPEND | PEER_FLAG_LOCAL_AS_REPLACE_AS)
#define PEER_UPDGRP_AF_FLAGS (PEER_FLAG_SEND_COMMUNITY | \
PEER_FLAG_SEND_EXT_COMMUNITY | \
PEER_FLAG_DEFAULT_ORIGINATE | \
PEER_FLAG_REFLECTOR_CLIENT | \
PEER_FLAG_RSERVER_CLIENT | \
PEER_FLAG_NEXTHOP_SELF | \
PEER_FLAG_NEXTHOP_UNCHANGED | \
PEER_FLAG_FORCE_NEXTHOP_SELF | \
PEER_FLAG_AS_PATH_UNCHANGED | \
PEER_FLAG_MED_UNCHANGED | \
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | \
PEER_FLAG_REMOVE_PRIVATE_AS | \
PEER_FLAG_REMOVE_PRIVATE_AS_ALL | \
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE | \
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE | \
PEER_FLAG_ADDPATH_TX_ALL_PATHS | \
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS | \
PEER_FLAG_AS_OVERRIDE)
#define PEER_UPDGRP_AF_FLAGS \
(PEER_FLAG_SEND_COMMUNITY | PEER_FLAG_SEND_EXT_COMMUNITY \
| PEER_FLAG_DEFAULT_ORIGINATE | PEER_FLAG_REFLECTOR_CLIENT \
| PEER_FLAG_RSERVER_CLIENT | PEER_FLAG_NEXTHOP_SELF \
| PEER_FLAG_NEXTHOP_UNCHANGED | PEER_FLAG_FORCE_NEXTHOP_SELF \
| PEER_FLAG_AS_PATH_UNCHANGED | PEER_FLAG_MED_UNCHANGED \
| PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | PEER_FLAG_REMOVE_PRIVATE_AS \
| PEER_FLAG_REMOVE_PRIVATE_AS_ALL \
| PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE \
| PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE \
| PEER_FLAG_ADDPATH_TX_ALL_PATHS \
| PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS | PEER_FLAG_AS_OVERRIDE)
#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
#define PEER_UPDGRP_AF_CAP_FLAGS (PEER_CAP_ORF_PREFIX_SM_RCV | \
PEER_CAP_ORF_PREFIX_SM_OLD_RCV |\
PEER_CAP_ADDPATH_AF_TX_ADV |\
PEER_CAP_ADDPATH_AF_RX_RCV |\
PEER_CAP_ENHE_AF_NEGO)
#define PEER_UPDGRP_AF_CAP_FLAGS \
(PEER_CAP_ORF_PREFIX_SM_RCV | PEER_CAP_ORF_PREFIX_SM_OLD_RCV \
| PEER_CAP_ADDPATH_AF_TX_ADV | PEER_CAP_ADDPATH_AF_RX_RCV \
| PEER_CAP_ENHE_AF_NEGO)
typedef enum
{
BGP_ATTR_VEC_NH = 0,
BGP_ATTR_VEC_MAX
} bpacket_attr_vec_type;
typedef enum { BGP_ATTR_VEC_NH = 0, BGP_ATTR_VEC_MAX } bpacket_attr_vec_type;
typedef struct
{
typedef struct {
u_int32_t flags;
unsigned long offset;
} bpacket_attr_vec;
@ -81,13 +69,11 @@ typedef struct
#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED (1 << 5)
#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_LNH_CHANGED (1 << 6)
typedef struct bpacket_attr_vec_arr
{
typedef struct bpacket_attr_vec_arr {
bpacket_attr_vec entries[BGP_ATTR_VEC_MAX];
} bpacket_attr_vec_arr;
struct bpacket
{
struct bpacket {
/* for being part of an update subgroup's message list */
TAILQ_ENTRY(bpacket) pkt_train;
@ -100,8 +86,7 @@ struct bpacket
unsigned int ver;
};
struct bpacket_queue
{
struct bpacket_queue {
TAILQ_HEAD(pkt_queue, bpacket) pkts;
#if 0
@ -116,8 +101,7 @@ struct bpacket_queue
unsigned int max_count_reached_count;
};
struct update_group
{
struct update_group {
/* back pointer to the BGP instance */
struct bgp *bgp;
@ -169,11 +153,9 @@ struct update_group
/*
* Increment a counter on a update group and its parent structures.
*/
#define UPDGRP_INCR_STAT(subgrp, stat) \
UPDGRP_INCR_STAT_BY(subgrp, stat, 1)
#define UPDGRP_INCR_STAT(subgrp, stat) UPDGRP_INCR_STAT_BY(subgrp, stat, 1)
struct update_subgroup
{
struct update_subgroup {
/* back pointer to the parent update group */
struct update_group *update_group;
@ -225,11 +207,11 @@ struct update_subgroup
time_t uptime;
/*
* Identifying information about the subgroup that this subgroup was split
* Identifying information about the subgroup that this subgroup was
* split
* from, if any.
*/
struct
{
struct {
uint64_t update_group_id;
uint64_t subgroup_id;
} split_from;
@ -271,27 +253,25 @@ struct update_subgroup
do { \
(subgrp)->stat += (value); \
if ((subgrp)->update_group) \
UPDGRP_INCR_STAT_BY((subgrp)->update_group, stat, value); \
UPDGRP_INCR_STAT_BY((subgrp)->update_group, stat, \
value); \
} while (0)
/*
* Increment a counter on a subgroup and its parent structures.
*/
#define SUBGRP_INCR_STAT(subgrp, stat) \
SUBGRP_INCR_STAT_BY(subgrp, stat, 1)
#define SUBGRP_INCR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, 1)
/*
* Decrement a counter on a subgroup and its parent structures.
*/
#define SUBGRP_DECR_STAT(subgrp, stat) \
SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
#define SUBGRP_DECR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
/* really a private structure */
struct updwalk_context
{
struct updwalk_context {
struct vty *vty;
struct bgp_node *rn;
struct bgp_info *ri;
@ -321,8 +301,7 @@ struct updwalk_context
#define UPDGRP_AFI(u) ((u)->afi)
#define UPDGRP_SAFI(u) ((u)->safi)
#define UPDGRP_INST(u) ((u)->bgp)
#define UPDGRP_AFFLAGS(u) \
((u)->conf->af_flags[UPDGRP_AFI(u)][UPDGRP_SAFI(u)])
#define UPDGRP_AFFLAGS(u) ((u)->conf->af_flags[UPDGRP_AFI(u)][UPDGRP_SAFI(u)])
#define UPDGRP_DBG_ON(u) ((u)->num_dbg_en_peers)
#define UPDGRP_PEER_DBG_EN(u) (((u)->num_dbg_en_peers)++)
#define UPDGRP_PEER_DBG_DIS(u) (((u)->num_dbg_en_peers)--)
@ -345,7 +324,8 @@ struct updwalk_context
LIST_FOREACH(subgrp, &((updgrp)->subgrps), updgrp_train)
#define UPDGRP_FOREACH_SUBGRP_SAFE(updgrp, subgrp, tmp_subgrp) \
LIST_FOREACH_SAFE(subgrp, &((updgrp)->subgrps), updgrp_train, tmp_subgrp)
LIST_FOREACH_SAFE(subgrp, &((updgrp)->subgrps), updgrp_train, \
tmp_subgrp)
#define SUBGRP_FOREACH_PEER(subgrp, paf) \
LIST_FOREACH(paf, &(subgrp->peers), subgrp_train)
@ -364,30 +344,28 @@ struct updwalk_context
extern void update_bgp_group_init(struct bgp *);
extern void udpate_bgp_group_free(struct bgp *);
extern void
update_group_show (struct bgp *bgp, afi_t afi, safi_t safi, struct vty *vty, uint64_t subgrp_id);
extern void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, uint64_t subgrp_id);
extern void update_group_show_stats(struct bgp *bgp, struct vty *vty);
extern void update_group_adjust_peer(struct peer_af *paf);
extern int update_group_adjust_soloness(struct peer *peer, int set);
extern void
update_subgroup_remove_peer (struct update_subgroup *, struct peer_af *);
extern void update_subgroup_remove_peer(struct update_subgroup *,
struct peer_af *);
extern struct bgp_table *update_subgroup_rib(struct update_subgroup *);
extern void
update_subgroup_split_peer (struct peer_af *, struct update_group *);
extern int
update_subgroup_check_merge (struct update_subgroup *, const char *);
extern int
update_subgroup_trigger_merge_check (struct update_subgroup *,
extern void update_subgroup_split_peer(struct peer_af *, struct update_group *);
extern int update_subgroup_check_merge(struct update_subgroup *, const char *);
extern int update_subgroup_trigger_merge_check(struct update_subgroup *,
int force);
extern void update_group_policy_update (struct bgp *bgp,
bgp_policy_type_e ptype, const char *pname,
int route_update, int start_event);
extern void update_group_policy_update(struct bgp *bgp, bgp_policy_type_e ptype,
const char *pname, int route_update,
int start_event);
extern void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
updgrp_walkcb cb, void *ctx);
extern void update_group_walk(struct bgp *bgp, updgrp_walkcb cb, void *ctx);
extern void update_group_periodic_merge(struct bgp *bgp);
extern int update_group_refresh_default_originate_route_map (struct thread *thread);
extern int
update_group_refresh_default_originate_route_map(struct thread *thread);
extern void update_group_start_advtimer(struct bgp *bgp);
extern void update_subgroup_inherit_info(struct update_subgroup *to,
@ -401,8 +379,7 @@ extern void bpacket_queue_cleanup (struct bpacket_queue *q);
extern void bpacket_queue_sanity_check(struct bpacket_queue *q);
extern struct bpacket *bpacket_queue_add(struct bpacket_queue *q,
struct stream *s,
struct bpacket_attr_vec_arr
*vecarr);
struct bpacket_attr_vec_arr *vecarr);
struct bpacket *bpacket_queue_remove(struct bpacket_queue *q);
extern struct bpacket *bpacket_queue_first(struct bpacket_queue *q);
struct bpacket *bpacket_queue_last(struct bpacket_queue *q);
@ -422,22 +399,18 @@ extern struct stream *bpacket_reformat_for_peer (struct bpacket *pkt,
extern void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr);
extern void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
bpacket_attr_vec_type type,
struct stream *s,
struct attr *attr);
extern void
subgroup_default_update_packet (struct update_subgroup *subgrp,
struct attr *attr, struct peer *from);
struct stream *s, struct attr *attr);
extern void subgroup_default_update_packet(struct update_subgroup *subgrp,
struct attr *attr,
struct peer *from);
extern void subgroup_default_withdraw_packet(struct update_subgroup *subgrp);
/* bgp_updgrp_adv.c */
extern struct bgp_advertise *bgp_advertise_clean_subgroup (struct
update_subgroup
*subgrp,
struct bgp_adj_out
*adj);
extern void update_group_show_adj_queue (struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
uint64_t id);
extern struct bgp_advertise *
bgp_advertise_clean_subgroup(struct update_subgroup *subgrp,
struct bgp_adj_out *adj);
extern void update_group_show_adj_queue(struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, uint64_t id);
extern void update_group_show_advertised(struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
uint64_t id);
@ -447,10 +420,9 @@ extern void update_group_show_packet_queue (struct bgp *bgp, afi_t afi,
extern void subgroup_announce_route(struct update_subgroup *subgrp);
extern void subgroup_announce_all(struct update_subgroup *subgrp);
extern void
subgroup_default_originate (struct update_subgroup *subgrp, int withdraw);
extern void
group_announce_route (struct bgp *bgp, afi_t afi, safi_t safi,
extern void subgroup_default_originate(struct update_subgroup *subgrp,
int withdraw);
extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
struct bgp_node *rn, struct bgp_info *ri);
extern void subgroup_clear_table(struct update_subgroup *subgrp);
extern void update_group_announce(struct bgp *bgp);
@ -462,23 +434,18 @@ extern struct bgp_adj_out *bgp_adj_out_alloc (struct update_subgroup *subgrp,
extern void bgp_adj_out_remove_subgroup(struct bgp_node *rn,
struct bgp_adj_out *adj,
struct update_subgroup *subgrp);
extern void
bgp_adj_out_set_subgroup (struct bgp_node *rn,
extern void bgp_adj_out_set_subgroup(struct bgp_node *rn,
struct update_subgroup *subgrp,
struct attr *attr, struct bgp_info *binfo);
extern void
bgp_adj_out_unset_subgroup (struct bgp_node *rn,
extern void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
struct update_subgroup *subgrp,
char withdraw,
u_int32_t addpath_tx_id);
void
subgroup_announce_table (struct update_subgroup *subgrp,
char withdraw, u_int32_t addpath_tx_id);
void subgroup_announce_table(struct update_subgroup *subgrp,
struct bgp_table *table);
extern void
subgroup_trigger_write (struct update_subgroup *subgrp);
extern void subgroup_trigger_write(struct update_subgroup *subgrp);
extern int
update_group_clear_update_dbg (struct update_group *updgrp, void *arg);
extern int update_group_clear_update_dbg(struct update_group *updgrp,
void *arg);
extern void update_bgp_group_free(struct bgp *bgp);
extern int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
@ -492,8 +459,7 @@ extern int bgp_addpath_tx_path (struct peer *peer, afi_t afi, safi_t safi,
/*
* bpacket_queue_is_empty
*/
static inline int
bpacket_queue_is_empty (struct bpacket_queue *queue)
static inline int bpacket_queue_is_empty(struct bpacket_queue *queue)
{
/*
@ -511,8 +477,7 @@ bpacket_queue_is_empty (struct bpacket_queue *queue)
*
* Returns the packet after the given packet in a bpacket queue.
*/
static inline struct bpacket *
bpacket_next (struct bpacket *pkt)
static inline struct bpacket *bpacket_next(struct bpacket *pkt)
{
return TAILQ_NEXT(pkt, pkt_train);
}
@ -522,14 +487,12 @@ bpacket_next (struct bpacket *pkt)
*
* Adjust all peer_af structures for the given peer.
*/
static inline void
update_group_adjust_peer_afs (struct peer *peer)
static inline void update_group_adjust_peer_afs(struct peer *peer)
{
struct peer_af *paf;
int afidx;
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++)
{
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer->peer_af_array[afidx];
if (paf != NULL)
update_group_adjust_peer(paf);
@ -541,14 +504,12 @@ update_group_adjust_peer_afs (struct peer *peer)
*
* Remove all peer_af structures for the given peer from their subgroups.
*/
static inline void
update_group_remove_peer_afs (struct peer *peer)
static inline void update_group_remove_peer_afs(struct peer *peer)
{
struct peer_af *paf;
int afidx;
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++)
{
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer->peer_af_array[afidx];
if (paf != NULL)
update_subgroup_remove_peer(PAF_SUBGRP(paf), paf);
@ -579,8 +540,8 @@ update_subgroup_set_needs_refresh (struct update_subgroup *subgrp, int value)
UNSET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
}
static inline struct update_subgroup *
peer_subgroup (struct peer *peer, afi_t afi, safi_t safi)
static inline struct update_subgroup *peer_subgroup(struct peer *peer,
afi_t afi, safi_t safi)
{
struct peer_af *paf;
@ -595,14 +556,12 @@ peer_subgroup (struct peer *peer, afi_t afi, safi_t safi)
*
* Adjust all peer_af structures for the given peer.
*/
static inline void
bgp_announce_peer (struct peer *peer)
static inline void bgp_announce_peer(struct peer *peer)
{
struct peer_af *paf;
int afidx;
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++)
{
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer->peer_af_array[afidx];
if (paf != NULL)
subgroup_announce_all(PAF_SUBGRP(paf));
@ -612,13 +571,11 @@ bgp_announce_peer (struct peer *peer)
/**
* advertise_list_is_empty
*/
static inline int
advertise_list_is_empty (struct update_subgroup *subgrp)
{
if (!BGP_ADV_FIFO_EMPTY (&subgrp->sync->update) ||
!BGP_ADV_FIFO_EMPTY (&subgrp->sync->withdraw) ||
!BGP_ADV_FIFO_EMPTY (&subgrp->sync->withdraw_low))
static inline int advertise_list_is_empty(struct update_subgroup *subgrp)
{
if (!BGP_ADV_FIFO_EMPTY(&subgrp->sync->update)
|| !BGP_ADV_FIFO_EMPTY(&subgrp->sync->withdraw)
|| !BGP_ADV_FIFO_EMPTY(&subgrp->sync->withdraw_low)) {
return 0;
}

View File

@ -55,8 +55,8 @@
* PRIVATE FUNCTIONS
********************/
static inline struct bgp_adj_out *
adj_lookup (struct bgp_node *rn, struct update_subgroup *subgrp,
static inline struct bgp_adj_out *adj_lookup(struct bgp_node *rn,
struct update_subgroup *subgrp,
u_int32_t addpath_tx_id)
{
struct bgp_adj_out *adj;
@ -75,19 +75,13 @@ adj_lookup (struct bgp_node *rn, struct update_subgroup *subgrp,
/* update-groups that do not support addpath will pass 0 for
* addpath_tx_id so do not both matching against it */
for (adj = rn->adj_out; adj; adj = adj->next)
{
if (adj->subgroup == subgrp)
{
if (addpath_capable)
{
if (adj->addpath_tx_id == addpath_tx_id)
{
for (adj = rn->adj_out; adj; adj = adj->next) {
if (adj->subgroup == subgrp) {
if (addpath_capable) {
if (adj->addpath_tx_id == addpath_tx_id) {
break;
}
}
else
{
} else {
break;
}
}
@ -96,16 +90,14 @@ adj_lookup (struct bgp_node *rn, struct update_subgroup *subgrp,
return adj;
}
static void
adj_free (struct bgp_adj_out *adj)
static void adj_free(struct bgp_adj_out *adj)
{
TAILQ_REMOVE(&(adj->subgroup->adjq), adj, subgrp_adj_train);
SUBGRP_DECR_STAT(adj->subgroup, adj_count);
XFREE(MTYPE_BGP_ADJ_OUT, adj);
}
static int
group_announce_route_walkcb (struct update_group *updgrp, void *arg)
static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
{
struct updwalk_context *ctx = arg;
struct update_subgroup *subgrp;
@ -129,67 +121,74 @@ group_announce_route_walkcb (struct update_group *updgrp, void *arg)
* walk the entire prefix table for those subgroups when the
* coalesce timer fires.
*/
if (!subgrp->t_coalesce)
{
if (!subgrp->t_coalesce) {
/* An update-group that uses addpath */
if (addpath_capable)
{
/* Look through all of the paths we have advertised for this rn and
* send a withdraw for the ones that are no longer present */
for (adj = ctx->rn->adj_out; adj; adj = adj_next)
{
if (addpath_capable) {
/* Look through all of the paths we have
* advertised for this rn and
* send a withdraw for the ones that are no
* longer present */
for (adj = ctx->rn->adj_out; adj;
adj = adj_next) {
adj_next = adj->next;
if (adj->subgroup == subgrp)
{
for (ri = ctx->rn->info; ri; ri = ri->next)
{
if (ri->addpath_tx_id == adj->addpath_tx_id)
{
if (adj->subgroup == subgrp) {
for (ri = ctx->rn->info; ri;
ri = ri->next) {
if (ri->addpath_tx_id
== adj->addpath_tx_id) {
break;
}
}
if (!ri)
{
subgroup_process_announce_selected (subgrp, NULL, ctx->rn, adj->addpath_tx_id);
if (!ri) {
subgroup_process_announce_selected(
subgrp, NULL,
ctx->rn,
adj->addpath_tx_id);
}
}
}
for (ri = ctx->rn->info; ri; ri = ri->next)
{
for (ri = ctx->rn->info; ri; ri = ri->next) {
/* Skip the bestpath for now */
if (ri == ctx->ri)
continue;
subgroup_process_announce_selected (subgrp, ri, ctx->rn, ri->addpath_tx_id);
subgroup_process_announce_selected(
subgrp, ri, ctx->rn,
ri->addpath_tx_id);
}
/* Process the bestpath last so the "show [ip] bgp neighbor x.x.x.x advertised"
* output shows the attributes from the bestpath */
/* Process the bestpath last so the "show [ip]
* bgp neighbor x.x.x.x advertised"
* output shows the attributes from the bestpath
*/
if (ctx->ri)
subgroup_process_announce_selected (subgrp, ctx->ri, ctx->rn, ctx->ri->addpath_tx_id);
subgroup_process_announce_selected(
subgrp, ctx->ri, ctx->rn,
ctx->ri->addpath_tx_id);
}
/* An update-group that does not use addpath */
else
{
if (ctx->ri)
{
subgroup_process_announce_selected (subgrp, ctx->ri, ctx->rn, ctx->ri->addpath_tx_id);
}
else
{
/* Find the addpath_tx_id of the path we had advertised and
else {
if (ctx->ri) {
subgroup_process_announce_selected(
subgrp, ctx->ri, ctx->rn,
ctx->ri->addpath_tx_id);
} else {
/* Find the addpath_tx_id of the path we
* had advertised and
* send a withdraw */
for (adj = ctx->rn->adj_out; adj; adj = adj_next)
{
for (adj = ctx->rn->adj_out; adj;
adj = adj_next) {
adj_next = adj->next;
if (adj->subgroup == subgrp)
{
subgroup_process_announce_selected (subgrp, NULL, ctx->rn, adj->addpath_tx_id);
if (adj->subgroup == subgrp) {
subgroup_process_announce_selected(
subgrp, NULL,
ctx->rn,
adj->addpath_tx_id);
}
}
}
@ -200,9 +199,8 @@ group_announce_route_walkcb (struct update_group *updgrp, void *arg)
return UPDWALK_CONTINUE;
}
static void
subgrp_show_adjq_vty (struct update_subgroup *subgrp, struct vty *vty,
u_int8_t flags)
static void subgrp_show_adjq_vty(struct update_subgroup *subgrp,
struct vty *vty, u_int8_t flags)
{
struct bgp_table *table;
struct bgp_adj_out *adj;
@ -222,40 +220,42 @@ subgrp_show_adjq_vty (struct update_subgroup *subgrp, struct vty *vty,
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
for (adj = rn->adj_out; adj; adj = adj->next)
if (adj->subgroup == subgrp)
{
if (header1)
{
vty_outln (vty,
"BGP table version is %" PRIu64 ", local router ID is %s",
table->version,inet_ntoa(bgp->router_id));
vty_outln (vty, BGP_SHOW_SCODE_HEADER, VTYNL);
vty_outln (vty, BGP_SHOW_OCODE_HEADER, VTYNL);
if (adj->subgroup == subgrp) {
if (header1) {
vty_out(vty,
"BGP table version is %" PRIu64
", local router ID is %s\n",
table->version,
inet_ntoa(bgp->router_id));
vty_out(vty, BGP_SHOW_SCODE_HEADER);
vty_out(vty, BGP_SHOW_OCODE_HEADER);
header1 = 0;
}
if (header2)
{
vty_outln (vty, BGP_SHOW_HEADER);
if (header2) {
vty_out(vty, BGP_SHOW_HEADER);
header2 = 0;
}
if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv && adj->adv->baa)
{
route_vty_out_tmp (vty, &rn->p, adj->adv->baa->attr, SUBGRP_SAFI (subgrp), 0, NULL);
if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv
&& adj->adv->baa) {
route_vty_out_tmp(vty, &rn->p,
adj->adv->baa->attr,
SUBGRP_SAFI(subgrp),
0, NULL);
output_count++;
}
if ((flags & UPDWALK_FLAGS_ADVERTISED) && adj->attr)
{
route_vty_out_tmp (vty, &rn->p, adj->attr, SUBGRP_SAFI (subgrp), 0, NULL);
if ((flags & UPDWALK_FLAGS_ADVERTISED)
&& adj->attr) {
route_vty_out_tmp(
vty, &rn->p, adj->attr,
SUBGRP_SAFI(subgrp), 0, NULL);
output_count++;
}
}
if (output_count != 0)
vty_outln (vty, "%sTotal number of prefixes %ld",
VTYNL, output_count);
vty_out(vty, "\nTotal number of prefixes %ld\n", output_count);
}
static int
updgrp_show_adj_walkcb (struct update_group *updgrp, void *arg)
static int updgrp_show_adj_walkcb(struct update_group *updgrp, void *arg)
{
struct updwalk_context *ctx = arg;
struct update_subgroup *subgrp;
@ -266,15 +266,14 @@ updgrp_show_adj_walkcb (struct update_group *updgrp, void *arg)
{
if (ctx->subgrp_id && (ctx->subgrp_id != subgrp->id))
continue;
vty_outln (vty, "update group %" PRIu64 ", subgroup %" PRIu64 "", updgrp->id,
subgrp->id);
vty_out(vty, "update group %" PRIu64 ", subgroup %" PRIu64 "\n",
updgrp->id, subgrp->id);
subgrp_show_adjq_vty(subgrp, vty, ctx->flags);
}
return UPDWALK_CONTINUE;
}
static void
updgrp_show_adj (struct bgp *bgp, afi_t afi, safi_t safi,
static void updgrp_show_adj(struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, uint64_t id, u_int8_t flags)
{
struct updwalk_context ctx;
@ -286,27 +285,29 @@ updgrp_show_adj (struct bgp *bgp, afi_t afi, safi_t safi,
update_group_af_walk(bgp, afi, safi, updgrp_show_adj_walkcb, &ctx);
}
static int
subgroup_coalesce_timer (struct thread *thread)
static int subgroup_coalesce_timer(struct thread *thread)
{
struct update_subgroup *subgrp;
subgrp = THREAD_ARG(thread);
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " announcing routes upon coalesce timer expiry",
zlog_debug("u%" PRIu64 ":s%" PRIu64
" announcing routes upon coalesce timer expiry",
(SUBGRP_UPDGRP(subgrp))->id, subgrp->id);
subgrp->t_coalesce = NULL;
subgrp->v_coalesce = 0;
subgroup_announce_route(subgrp);
/* While the announce_route() may kick off the route advertisement timer for
* the members of the subgroup, we'd like to send the initial updates much
* faster (i.e., without enforcing MRAI). Also, if there were no routes to
/* While the announce_route() may kick off the route advertisement timer
* for
* the members of the subgroup, we'd like to send the initial updates
* much
* faster (i.e., without enforcing MRAI). Also, if there were no routes
* to
* announce, this is the method currently employed to trigger the EOR.
*/
if (!bgp_update_delay_active(SUBGRP_INST(subgrp)))
{
if (!bgp_update_delay_active(SUBGRP_INST(subgrp))) {
struct peer_af *paf;
struct peer *peer;
@ -321,8 +322,7 @@ subgroup_coalesce_timer (struct thread *thread)
return 0;
}
static int
update_group_announce_walkcb (struct update_group *updgrp, void *arg)
static int update_group_announce_walkcb(struct update_group *updgrp, void *arg)
{
struct update_subgroup *subgrp;
@ -334,8 +334,8 @@ update_group_announce_walkcb (struct update_group *updgrp, void *arg)
return UPDWALK_CONTINUE;
}
static int
update_group_announce_rrc_walkcb (struct update_group *updgrp, void *arg)
static int update_group_announce_rrc_walkcb(struct update_group *updgrp,
void *arg)
{
struct update_subgroup *subgrp;
afi_t afi;
@ -347,8 +347,7 @@ update_group_announce_rrc_walkcb (struct update_group *updgrp, void *arg)
peer = UPDGRP_PEER(updgrp);
/* Only announce if this is a group of route-reflector-clients */
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
{
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)) {
UPDGRP_FOREACH_SUBGRP(updgrp, subgrp)
{
subgroup_announce_all(subgrp);
@ -366,16 +365,15 @@ update_group_announce_rrc_walkcb (struct update_group *updgrp, void *arg)
* Allocate an adj-out object. Do proper initialization of its fields,
* primarily its association with the subgroup and the prefix.
*/
struct bgp_adj_out *
bgp_adj_out_alloc (struct update_subgroup *subgrp, struct bgp_node *rn,
struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp,
struct bgp_node *rn,
u_int32_t addpath_tx_id)
{
struct bgp_adj_out *adj;
adj = XCALLOC(MTYPE_BGP_ADJ_OUT, sizeof(struct bgp_adj_out));
adj->subgroup = subgrp;
if (rn)
{
if (rn) {
BGP_ADJ_OUT_ADD(rn, adj);
bgp_lock_node(rn);
adj->rn = rn;
@ -401,8 +399,7 @@ bgp_advertise_clean_subgroup (struct update_subgroup *subgrp,
baa = adv->baa;
next = NULL;
if (baa)
{
if (baa) {
fhead = &subgrp->sync->update;
/* Unlink myself from advertise attribute FIFO. */
@ -413,8 +410,7 @@ bgp_advertise_clean_subgroup (struct update_subgroup *subgrp,
/* Unintern BGP advertise attribute. */
bgp_advertise_unintern(subgrp->hash, baa);
}
else
} else
fhead = &subgrp->sync->withdraw;
@ -428,10 +424,9 @@ bgp_advertise_clean_subgroup (struct update_subgroup *subgrp,
return next;
}
void
bgp_adj_out_set_subgroup (struct bgp_node *rn,
struct update_subgroup *subgrp,
struct attr *attr, struct bgp_info *binfo)
void bgp_adj_out_set_subgroup(struct bgp_node *rn,
struct update_subgroup *subgrp, struct attr *attr,
struct bgp_info *binfo)
{
struct bgp_adj_out *adj = NULL;
struct bgp_advertise *adv;
@ -442,8 +437,7 @@ bgp_adj_out_set_subgroup (struct bgp_node *rn,
/* Look for adjacency information. */
adj = adj_lookup(rn, subgrp, binfo->addpath_tx_id);
if (!adj)
{
if (!adj) {
adj = bgp_adj_out_alloc(subgrp, rn, binfo->addpath_tx_id);
if (!adj)
return;
@ -471,8 +465,7 @@ bgp_adj_out_set_subgroup (struct bgp_node *rn,
* If the update adv list is empty, trigger the member peers'
* mrai timers so the socket writes can happen.
*/
if (BGP_ADV_FIFO_EMPTY (&subgrp->sync->update))
{
if (BGP_ADV_FIFO_EMPTY(&subgrp->sync->update)) {
struct peer_af *paf;
SUBGRP_FOREACH_PEER(subgrp, paf)
@ -490,10 +483,8 @@ bgp_adj_out_set_subgroup (struct bgp_node *rn,
* the "neighbor x.x.x.x default-originate" default and need to clear
* bgp_adj_out for the 0.0.0.0/0 route in the BGP table.
*/
void
bgp_adj_out_unset_subgroup (struct bgp_node *rn,
struct update_subgroup *subgrp,
char withdraw,
void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
struct update_subgroup *subgrp, char withdraw,
u_int32_t addpath_tx_id)
{
struct bgp_adj_out *adj;
@ -504,14 +495,12 @@ bgp_adj_out_unset_subgroup (struct bgp_node *rn,
return;
/* Lookup existing adjacency */
if ((adj = adj_lookup (rn, subgrp, addpath_tx_id)) != NULL)
{
if ((adj = adj_lookup(rn, subgrp, addpath_tx_id)) != NULL) {
/* Clean up previous advertisement. */
if (adj->adv)
bgp_advertise_clean_subgroup(subgrp, adj);
if (adj->attr && withdraw)
{
if (adj->attr && withdraw) {
/* We need advertisement structure. */
adj->adv = bgp_advertise_new();
adv = adj->adv;
@ -524,15 +513,15 @@ bgp_adj_out_unset_subgroup (struct bgp_node *rn,
else
trigger_write = 0;
/* Add to synchronization entry for withdraw announcement. */
/* Add to synchronization entry for withdraw
* announcement. */
BGP_ADV_FIFO_ADD(&subgrp->sync->withdraw, &adv->fifo);
/* Schedule packet write, if FIFO is getting its first entry. */
/* Schedule packet write, if FIFO is getting its first
* entry. */
if (trigger_write)
subgroup_trigger_write(subgrp);
}
else
{
} else {
/* Remove myself from adjacency. */
BGP_ADJ_OUT_DEL(rn, adj);
@ -546,8 +535,7 @@ bgp_adj_out_unset_subgroup (struct bgp_node *rn,
subgrp->version = max(subgrp->version, rn->version);
}
void
bgp_adj_out_remove_subgroup (struct bgp_node *rn, struct bgp_adj_out *adj,
void bgp_adj_out_remove_subgroup(struct bgp_node *rn, struct bgp_adj_out *adj,
struct update_subgroup *subgrp)
{
if (adj->attr)
@ -564,8 +552,7 @@ bgp_adj_out_remove_subgroup (struct bgp_node *rn, struct bgp_adj_out *adj,
* Go through all the routes and clean up the adj/adv structures corresponding
* to the subgroup.
*/
void
subgroup_clear_table (struct update_subgroup *subgrp)
void subgroup_clear_table(struct update_subgroup *subgrp)
{
struct bgp_adj_out *aout, *taout;
@ -580,14 +567,12 @@ subgroup_clear_table (struct update_subgroup *subgrp)
/*
* subgroup_announce_table
*/
void
subgroup_announce_table (struct update_subgroup *subgrp,
void subgroup_announce_table(struct update_subgroup *subgrp,
struct bgp_table *table)
{
struct bgp_node *rn;
struct bgp_info *ri;
struct attr attr;
struct attr_extra extra;
struct peer *peer;
afi_t afi;
safi_t safi;
@ -598,28 +583,31 @@ subgroup_announce_table (struct update_subgroup *subgrp,
safi = SUBGRP_SAFI(subgrp);
addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
if (safi == SAFI_LABELED_UNICAST)
safi = SAFI_UNICAST;
if (!table)
table = peer->bgp->rib[afi][safi];
if (safi != SAFI_MPLS_VPN
&& safi != SAFI_ENCAP
&& safi != SAFI_EVPN
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN
&& CHECK_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_DEFAULT_ORIGINATE))
subgroup_default_originate(subgrp, 0);
/* It's initialized in bgp_announce_check() */
attr.extra = &extra;
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
for (ri = rn->info; ri; ri = ri->next)
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) ||
(addpath_capable && bgp_addpath_tx_path(peer, afi, safi, ri)))
{
if (subgroup_announce_check (rn, ri, subgrp, &rn->p, &attr))
bgp_adj_out_set_subgroup (rn, subgrp, &attr, ri);
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
|| (addpath_capable
&& bgp_addpath_tx_path(peer, afi, safi, ri))) {
if (subgroup_announce_check(rn, ri, subgrp,
&rn->p, &attr))
bgp_adj_out_set_subgroup(rn, subgrp,
&attr, ri);
else
bgp_adj_out_unset_subgroup (rn, subgrp, 1, ri->addpath_tx_id);
bgp_adj_out_unset_subgroup(
rn, subgrp, 1,
ri->addpath_tx_id);
}
/*
@ -643,32 +631,29 @@ subgroup_announce_table (struct update_subgroup *subgrp,
*
* Refresh all routes out to a subgroup.
*/
void
subgroup_announce_route (struct update_subgroup *subgrp)
void subgroup_announce_route(struct update_subgroup *subgrp)
{
struct bgp_node *rn;
struct bgp_table *table;
struct peer *onlypeer;
if (update_subgroup_needs_refresh (subgrp))
{
if (update_subgroup_needs_refresh(subgrp)) {
update_subgroup_set_needs_refresh(subgrp, 0);
}
/*
* First update is deferred until ORF or ROUTE-REFRESH is received
*/
onlypeer = ((SUBGRP_PCOUNT (subgrp) == 1) ?
(SUBGRP_PFIRST (subgrp))->peer : NULL);
if (onlypeer &&
CHECK_FLAG (onlypeer->
af_sflags[SUBGRP_AFI (subgrp)][SUBGRP_SAFI (subgrp)],
onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
: NULL);
if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[SUBGRP_AFI(subgrp)]
[SUBGRP_SAFI(subgrp)],
PEER_STATUS_ORF_WAIT_REFRESH))
return;
if (SUBGRP_SAFI (subgrp) != SAFI_MPLS_VPN &&
SUBGRP_SAFI (subgrp) != SAFI_ENCAP &&
SUBGRP_SAFI (subgrp) != SAFI_EVPN)
if (SUBGRP_SAFI(subgrp) != SAFI_MPLS_VPN
&& SUBGRP_SAFI(subgrp) != SAFI_ENCAP
&& SUBGRP_SAFI(subgrp) != SAFI_EVPN)
subgroup_announce_table(subgrp, NULL);
else
for (rn = bgp_table_top(update_subgroup_rib(subgrp)); rn;
@ -677,8 +662,7 @@ subgroup_announce_route (struct update_subgroup *subgrp)
subgroup_announce_table(subgrp, table);
}
void
subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
{
struct bgp *bgp;
struct attr attr;
@ -711,45 +695,39 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
if (afi == AFI_IP)
str2prefix("0.0.0.0/0", &p);
else if (afi == AFI_IP6)
{
struct attr_extra *ae = attr.extra;
else if (afi == AFI_IP6) {
str2prefix("::/0", &p);
/* IPv6 global nexthop must be included. */
ae->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
/* If the peer is on shared nextwork and we have link-local
nexthop set it. */
if (peer->shared_network
&& !IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_local))
ae->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
}
if (peer->default_rmap[afi][safi].name)
{
if (peer->default_rmap[afi][safi].name) {
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
rn = bgp_route_next (rn))
{
for (ri = rn->info; ri; ri = ri->next)
{
rn = bgp_route_next(rn)) {
for (ri = rn->info; ri; ri = ri->next) {
struct attr dummy_attr;
struct attr_extra dummy_extra;
struct bgp_info info;
/* Provide dummy so the route-map can't modify the attributes */
dummy_attr.extra = &dummy_extra;
/* Provide dummy so the route-map can't modify
* the attributes */
bgp_attr_dup(&dummy_attr, ri->attr);
info.peer = ri->peer;
info.attr = &dummy_attr;
ret =
route_map_apply (peer->default_rmap[afi][safi].map, &rn->p,
RMAP_BGP, &info);
ret = route_map_apply(
peer->default_rmap[afi][safi].map,
&rn->p, RMAP_BGP, &info);
/* The route map might have set attributes. If we don't flush them
/* The route map might have set attributes. If
* we don't flush them
* here, they will be leaked. */
bgp_attr_flush(&dummy_attr);
if (ret != RMAP_DENYMATCH)
@ -764,34 +742,37 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
withdraw = 1;
}
if (withdraw)
{
if (withdraw) {
if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
subgroup_default_withdraw_packet(subgrp);
UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE);
}
else
{
if (!CHECK_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
{
SET_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE);
} else {
if (!CHECK_FLAG(subgrp->sflags,
SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
SET_FLAG(subgrp->sflags,
SUBGRP_STATUS_DEFAULT_ORIGINATE);
subgroup_default_update_packet(subgrp, &attr, from);
/* The 'neighbor x.x.x.x default-originate' default will act as an
* implicit withdraw for any previous UPDATEs sent for 0.0.0.0/0 so
* clear adj_out for the 0.0.0.0/0 prefix in the BGP table.
/* The 'neighbor x.x.x.x default-originate' default will
* act as an
* implicit withdraw for any previous UPDATEs sent for
* 0.0.0.0/0 so
* clear adj_out for the 0.0.0.0/0 prefix in the BGP
* table.
*/
if (afi == AFI_IP)
str2prefix("0.0.0.0/0", &p);
else
str2prefix("::/0", &p);
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, &p, NULL);
bgp_adj_out_unset_subgroup (rn, subgrp, 0, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
&p, NULL);
bgp_adj_out_unset_subgroup(
rn, subgrp, 0,
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
}
}
bgp_attr_extra_free (&attr);
aspath_unintern(&aspath);
}
@ -803,8 +784,7 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
* subgrp->v_coalesce will be set to zero and the normal logic
* prevails.
*/
void
subgroup_announce_all (struct update_subgroup *subgrp)
void subgroup_announce_all(struct update_subgroup *subgrp)
{
if (!subgrp)
return;
@ -812,10 +792,10 @@ subgroup_announce_all (struct update_subgroup *subgrp)
/*
* If coalesce timer value is not set, announce routes immediately.
*/
if (!subgrp->v_coalesce)
{
if (!subgrp->v_coalesce) {
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " announcing all routes",
zlog_debug("u%" PRIu64 ":s%" PRIu64
" announcing all routes",
subgrp->update_group->id, subgrp->id);
subgroup_announce_route(subgrp);
return;
@ -824,10 +804,10 @@ subgroup_announce_all (struct update_subgroup *subgrp)
/*
* We should wait for the coalesce timer. Arm the timer if not done.
*/
if (!subgrp->t_coalesce)
{
thread_add_timer_msec(bm->master, subgroup_coalesce_timer, subgrp,
subgrp->v_coalesce, &subgrp->t_coalesce);
if (!subgrp->t_coalesce) {
thread_add_timer_msec(bm->master, subgroup_coalesce_timer,
subgrp, subgrp->v_coalesce,
&subgrp->t_coalesce);
}
}
@ -835,8 +815,7 @@ subgroup_announce_all (struct update_subgroup *subgrp)
* Go through all update subgroups and set up the adv queue for the
* input route.
*/
void
group_announce_route (struct bgp *bgp, afi_t afi, safi_t safi,
void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
struct bgp_node *rn, struct bgp_info *ri)
{
struct updwalk_context ctx;
@ -845,28 +824,24 @@ group_announce_route (struct bgp *bgp, afi_t afi, safi_t safi,
update_group_af_walk(bgp, afi, safi, group_announce_route_walkcb, &ctx);
}
void
update_group_show_adj_queue (struct bgp *bgp, afi_t afi, safi_t safi,
void update_group_show_adj_queue(struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, uint64_t id)
{
updgrp_show_adj(bgp, afi, safi, vty, id, UPDWALK_FLAGS_ADVQUEUE);
}
void
update_group_show_advertised (struct bgp *bgp, afi_t afi, safi_t safi,
void update_group_show_advertised(struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, uint64_t id)
{
updgrp_show_adj(bgp, afi, safi, vty, id, UPDWALK_FLAGS_ADVERTISED);
}
void
update_group_announce (struct bgp *bgp)
void update_group_announce(struct bgp *bgp)
{
update_group_walk(bgp, update_group_announce_walkcb, NULL);
}
void
update_group_announce_rrclients (struct bgp *bgp)
void update_group_announce_rrclients(struct bgp *bgp)
{
update_group_walk(bgp, update_group_announce_rrc_walkcb, NULL);
}

File diff suppressed because it is too large Load Diff

View File

@ -30,9 +30,9 @@
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_vpn.h"
int
show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
afi_t afi, safi_t safi, u_char use_json)
int show_adj_route_vpn(struct vty *vty, struct peer *peer,
struct prefix_rd *prd, afi_t afi, safi_t safi,
u_char use_json)
{
struct bgp *bgp;
struct bgp_table *table;
@ -48,15 +48,13 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
json_object *json_array = NULL;
bgp = bgp_get_default();
if (bgp == NULL)
{
if (bgp == NULL) {
if (!use_json)
vty_outln (vty, "No BGP process is configured");
vty_out(vty, "No BGP process is configured\n");
return CMD_WARNING;
}
if (use_json)
{
if (use_json) {
json_scode = json_object_new_object();
json_ocode = json_object_new_object();
json_routes = json_object_new_object();
@ -75,13 +73,11 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
}
for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
rn = bgp_route_next (rn))
{
rn = bgp_route_next(rn)) {
if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
continue;
if ((table = rn->info) != NULL)
{
if ((table = rn->info) != NULL) {
if (use_json)
json_array = json_object_new_array();
else
@ -89,39 +85,49 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
rd_header = 1;
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
{
if ((attr = rm->info) != NULL)
{
if (header)
{
if (use_json)
{
json_object_int_add(json, "bgpTableVersion", 0);
json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
json_object_object_add(json, "bgpStatusCodes", json_scode);
json_object_object_add(json, "bgpOriginCodes", json_ocode);
}
else
{
vty_outln (vty, "BGP table version is 0, local router ID is %s",
inet_ntoa(bgp->router_id));
vty_outln (vty,
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal");
vty_outln (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s",
VTYNL);
vty_outln (vty, V4_HEADER);
for (rm = bgp_table_top(table); rm;
rm = bgp_route_next(rm)) {
if ((attr = rm->info) != NULL) {
if (header) {
if (use_json) {
json_object_int_add(
json,
"bgpTableVersion",
0);
json_object_string_add(
json,
"bgpLocalRouterId",
inet_ntoa(
bgp->router_id));
json_object_object_add(
json,
"bgpStatusCodes",
json_scode);
json_object_object_add(
json,
"bgpOriginCodes",
json_ocode);
} else {
vty_out(vty,
"BGP table version is 0, local router ID is %s\n",
inet_ntoa(
bgp->router_id));
vty_out(vty,
"Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
vty_out(vty,
"Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
vty_out(vty, V4_HEADER);
}
header = 0;
}
if (rd_header)
{
if (rd_header) {
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip = {0};
#if ENABLE_BGP_VNC
struct rd_vnc_eth rd_vnc_eth = {0};
struct rd_vnc_eth rd_vnc_eth = {
0};
#endif
u_char *pnt;
@ -131,70 +137,114 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
type = decode_rd_type(pnt);
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as (pnt + 2, &rd_as);
decode_rd_as(pnt + 2,
&rd_as);
else if (type == RD_TYPE_AS4)
decode_rd_as4 (pnt + 2, &rd_as);
decode_rd_as4(pnt + 2,
&rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 2, &rd_ip);
decode_rd_ip(pnt + 2,
&rd_ip);
#if ENABLE_BGP_VNC
else if (type == RD_TYPE_VNC_ETH)
decode_rd_vnc_eth (pnt, &rd_vnc_eth);
else if (type
== RD_TYPE_VNC_ETH)
decode_rd_vnc_eth(
pnt,
&rd_vnc_eth);
#endif
if (use_json)
{
if (use_json) {
char buffer[BUFSIZ];
if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
json_object_string_add(json_routes, "routeDistinguisher", buffer);
}
else
{
vty_out (vty, "Route Distinguisher: ");
if (type == RD_TYPE_AS
|| type == RD_TYPE_AS4)
sprintf(buffer,
"%u:%d",
rd_as.as,
rd_as.val);
else if (type
== RD_TYPE_IP)
sprintf(buffer,
"%s:%d",
inet_ntoa(
rd_ip.ip),
rd_ip.val);
json_object_string_add(
json_routes,
"routeDistinguisher",
buffer);
} else {
vty_out(vty,
"Route Distinguisher: ");
if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
if (type == RD_TYPE_AS
|| type == RD_TYPE_AS4)
vty_out(vty,
"%u:%d",
rd_as.as,
rd_as.val);
else if (type
== RD_TYPE_IP)
vty_out(vty,
"%s:%d",
inet_ntoa(
rd_ip.ip),
rd_ip.val);
#if ENABLE_BGP_VNC
else if (type == RD_TYPE_VNC_ETH)
vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
rd_vnc_eth.local_nve_id,
rd_vnc_eth.macaddr.octet[0],
rd_vnc_eth.macaddr.octet[1],
rd_vnc_eth.macaddr.octet[2],
rd_vnc_eth.macaddr.octet[3],
rd_vnc_eth.macaddr.octet[4],
rd_vnc_eth.macaddr.octet[5]);
else if (
type
== RD_TYPE_VNC_ETH)
vty_out(vty,
"%u:%02x:%02x:%02x:%02x:%02x:%02x",
rd_vnc_eth
.local_nve_id,
rd_vnc_eth
.macaddr
.octet[0],
rd_vnc_eth
.macaddr
.octet[1],
rd_vnc_eth
.macaddr
.octet[2],
rd_vnc_eth
.macaddr
.octet[3],
rd_vnc_eth
.macaddr
.octet[4],
rd_vnc_eth
.macaddr
.octet[5]);
#endif
vty_out (vty, VTYNL);
vty_out(vty, "\n");
}
rd_header = 0;
}
route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN, use_json, json_array);
route_vty_out_tmp(vty, &rm->p, attr,
SAFI_MPLS_VPN,
use_json, json_array);
}
}
if (use_json)
{
if (use_json) {
struct prefix *p;
char buf_a[BUFSIZ];
char buf_b[BUFSIZ];
p = &rm->p;
sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
json_object_object_add(json_routes, buf_a, json_array);
sprintf(buf_a, "%s/%d",
inet_ntop(p->family, &p->u.prefix,
buf_b, BUFSIZ),
p->prefixlen);
json_object_object_add(json_routes, buf_a,
json_array);
}
}
}
if (use_json)
{
if (use_json) {
json_object_object_add(json, "routes", json_routes);
vty_outln (vty, "%s",
json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
}
return CMD_SUCCESS;
}

View File

@ -23,8 +23,8 @@
#include <zebra.h>
extern int
show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
afi_t afi, safi_t safi, u_char use_json);
extern int show_adj_route_vpn(struct vty *vty, struct peer *peer,
struct prefix_rd *prd, afi_t afi, safi_t safi,
u_char use_json);
#endif /* _QUAGGA_BGP_VPN_H */

File diff suppressed because it is too large Load Diff

View File

@ -28,15 +28,21 @@ struct bgp;
#define BGP_AFI_CMD_STR "<ipv4|ipv6>"
#define BGP_AFI_HELP_STR "Address Family\nAddress Family\n"
#define BGP_SAFI_CMD_STR "<unicast|multicast|vpn|labeled-unicast>"
#define BGP_SAFI_CMD_STR "<unicast|multicast|vpn>"
#define BGP_SAFI_HELP_STR \
"Address Family modifier\n" \
"Address Family modifier\n" \
"Address Family modifier\n" \
"Address Family modifier\n"
#define BGP_AFI_SAFI_CMD_STR BGP_AFI_CMD_STR" "BGP_SAFI_CMD_STR
#define BGP_AFI_SAFI_HELP_STR BGP_AFI_HELP_STR BGP_SAFI_HELP_STR
#define BGP_SAFI_WITH_LABEL_CMD_STR "<unicast|multicast|vpn|labeled-unicast>"
#define BGP_SAFI_WITH_LABEL_HELP_STR \
"Address Family modifier\n" \
"Address Family modifier\n" \
"Address Family modifier\n" \
"Address Family modifier\n"
extern void bgp_vty_init(void);
extern const char *afi_safi_print(afi_t, safi_t);
extern const char *afi_safi_json(afi_t, safi_t);
@ -45,22 +51,23 @@ extern int bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp);
extern int bgp_config_write_listen(struct vty *vty, struct bgp *bgp);
extern int bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp);
extern int bgp_vty_return(struct vty *vty, int ret);
extern struct peer *
peer_and_group_lookup_vty (struct vty *vty, const char *peer_str);
extern struct peer *peer_and_group_lookup_vty(struct vty *vty,
const char *peer_str);
extern afi_t
bgp_vty_afi_from_str(const char *afi_str);
extern afi_t bgp_vty_afi_from_str(const char *afi_str);
extern safi_t
bgp_vty_safi_from_str(const char *safi_str);
extern safi_t bgp_vty_safi_from_str(const char *safi_str);
extern int
argv_find_and_parse_afi(struct cmd_token **argv, int argc, int *index, afi_t *afi);
extern int argv_find_and_parse_afi(struct cmd_token **argv, int argc,
int *index, afi_t *afi);
extern int
argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index, safi_t *safi);
extern int argv_find_and_parse_safi(struct cmd_token **argv, int argc,
int *index, safi_t *safi);
extern int
bgp_vty_find_and_parse_afi_safi_bgp (struct vty *vty, struct cmd_token **argv, int argc, int *idx,
afi_t *afi, safi_t *safi, struct bgp **bgp);
extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
struct cmd_token **argv,
int argc, int *idx, afi_t *afi,
safi_t *safi, struct bgp **bgp);
extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
safi_t safi, u_char use_json);
#endif /* _QUAGGA_BGP_VTY_H */

File diff suppressed because it is too large Load Diff

View File

@ -21,21 +21,13 @@
#ifndef _QUAGGA_BGP_ZEBRA_H
#define _QUAGGA_BGP_ZEBRA_H
#define BGP_NEXTHOP_BUF_SIZE (8 * sizeof (struct in_addr *))
#define BGP_IFINDICES_BUF_SIZE (8 * sizeof (unsigned int))
#define BGP_LABEL_BUF_SIZE (8 * sizeof (unsigned int))
extern struct stream *bgp_nexthop_buf;
extern struct stream *bgp_ifindices_buf;
extern struct stream *bgp_label_buf;
extern void bgp_zebra_init(struct thread_master *master);
extern void bgp_zebra_destroy(void);
extern int bgp_if_update_all(void);
extern int bgp_config_write_maxpaths (struct vty *, struct bgp *, afi_t,
safi_t, int *);
extern int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t,
extern int bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t, safi_t,
int *);
extern int bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t,
safi_t, int *);
extern void bgp_zebra_announce(struct bgp_node *, struct prefix *,
struct bgp_info *, struct bgp *, afi_t, safi_t);
extern void bgp_zebra_announce_table(struct bgp *, afi_t, safi_t);
@ -47,20 +39,25 @@ extern void bgp_zebra_terminate_radv (struct bgp *bgp, struct peer *peer);
extern void bgp_zebra_instance_register(struct bgp *);
extern void bgp_zebra_instance_deregister(struct bgp *);
extern struct bgp_redist *bgp_redist_lookup (struct bgp *, afi_t, u_char, u_short);
extern struct bgp_redist *bgp_redist_lookup(struct bgp *, afi_t, u_char,
u_short);
extern struct bgp_redist *bgp_redist_add(struct bgp *, afi_t, u_char, u_short);
extern int bgp_redistribute_set(struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_resend(struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_rmap_set(struct bgp_redist *, const char *);
extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *,
afi_t, int, u_int32_t);
extern int bgp_redistribute_metric_set(struct bgp *, struct bgp_redist *, afi_t,
int, u_int32_t);
extern int bgp_redistribute_unset(struct bgp *, afi_t, int, u_short);
extern int bgp_redistribute_unreg(struct bgp *, afi_t, int, u_short);
extern struct interface *if_lookup_by_ipv4(struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv4_exact(struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, ifindex_t, vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, ifindex_t, vrf_id_t);
extern struct interface *if_lookup_by_ipv6(struct in6_addr *, ifindex_t,
vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact(struct in6_addr *, ifindex_t,
vrf_id_t);
extern int bgp_zebra_advertise_all_vni(struct bgp *, int);
extern int bgp_zebra_num_connects(void);

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,7 @@
#include "linklist.h"
#include "defaults.h"
#include "bgp_memory.h"
#include "bitfield.h"
#define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */
@ -44,11 +45,11 @@ struct bpacket;
/*
* Allow the neighbor XXXX remote-as to take internal or external
* AS_SPECIFIED is zero to auto-inherit original non-feature/enhancement behavior
* AS_SPECIFIED is zero to auto-inherit original non-feature/enhancement
* behavior
* in the system.
*/
enum {
AS_UNSPECIFIED = 0,
enum { AS_UNSPECIFIED = 0,
AS_SPECIFIED,
AS_INTERNAL,
AS_EXTERNAL,
@ -60,12 +61,13 @@ typedef u_int16_t as16_t; /* we may still encounter 16 Bit asnums */
typedef u_int16_t bgp_size_t;
#define max(a, b) \
({ __typeof__ (a) _a = (a); \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; })
_a > _b ? _a : _b; \
})
enum bgp_af_index
{
enum bgp_af_index {
BGP_AF_START,
BGP_AF_IPV4_UNICAST = BGP_AF_START,
BGP_AF_IPV4_MULTICAST,
@ -81,16 +83,14 @@ enum bgp_af_index
BGP_AF_MAX
};
#define AF_FOREACH(af) \
for ((af) = BGP_AF_START; (af) < BGP_AF_MAX; (af)++)
#define AF_FOREACH(af) for ((af) = BGP_AF_START; (af) < BGP_AF_MAX; (af)++)
#define FOREACH_AFI_SAFI(afi, safi) \
for (afi = AFI_IP; afi < AFI_MAX; afi++) \
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
/* BGP master for system wide configurations and variables. */
struct bgp_master
{
struct bgp_master {
/* BGP instance list. */
struct list *bgp;
@ -125,6 +125,8 @@ struct bgp_master
/* timer to dampen route map changes */
struct thread *t_rmap_update; /* Handle route map updates */
u_int32_t rmap_update_timer; /* Route map update timer */
/* $FRR indent$ */
/* clang-format off */
#define RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */
QOBJ_FIELDS
@ -132,14 +134,12 @@ struct bgp_master
DECLARE_QOBJ_TYPE(bgp_master)
/* BGP route-map structure. */
struct bgp_rmap
{
struct bgp_rmap {
char *name;
struct route_map *map;
};
struct bgp_redist
{
struct bgp_redist {
u_short instance;
/* BGP redistribute metric configuration. */
@ -158,16 +158,14 @@ struct bgp_redist
* The "default" instance is treated separately to simplify the code. Note
* that if deployed in a Multi-VRF environment, it may not exist.
*/
enum bgp_instance_type
{
enum bgp_instance_type {
BGP_INSTANCE_TYPE_DEFAULT,
BGP_INSTANCE_TYPE_VRF,
BGP_INSTANCE_TYPE_VIEW
};
/* BGP instance structure. */
struct bgp
{
struct bgp {
/* AS number of this BGP instance. */
as_t as;
@ -236,17 +234,26 @@ struct bgp
as_t *confed_peers;
int confed_peers_cnt;
struct thread *t_startup; /* start-up timer on only once at the beginning */
struct thread
*t_startup; /* start-up timer on only once at the beginning */
u_int32_t v_maxmed_onstartup; /* Duration of max-med on start-up */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_ONSTARTUP_UNCONFIGURED 0 /* 0 means off, its the default */
u_int32_t maxmed_onstartup_value; /* Max-med value when active on start-up */
struct thread *t_maxmed_onstartup; /* non-null when max-med onstartup is on */
u_int32_t maxmed_onstartup_value; /* Max-med value when active on
start-up */
struct thread
*t_maxmed_onstartup; /* non-null when max-med onstartup is on */
u_char maxmed_onstartup_over; /* Flag to make it effective only once */
u_char v_maxmed_admin; /* 1/0 if max-med administrative is on/off */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */
u_int32_t maxmed_admin_value; /* Max-med value when administrative in on */
u_int32_t
maxmed_admin_value; /* Max-med value when administrative in on
*/
#define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */
u_char maxmed_active; /* 1/0 if max-med is active or not */
@ -367,6 +374,20 @@ struct bgp
struct rfapi *rfapi;
#endif
/* EVPN related information */
/* EVI hash table */
struct hash *vnihash;
/* EVPN enable - advertise local VNIs and their MACs etc. */
int advertise_all_vni;
/* Hash table of Import RTs to EVIs */
struct hash *import_rt_hash;
/* Id space for automatic RD derivation for an EVI */
bitfield_t rd_idspace;
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(bgp)
@ -374,12 +395,12 @@ DECLARE_QOBJ_TYPE(bgp)
#define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold)
#define IS_BGP_INST_KNOWN_TO_ZEBRA(bgp) \
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT || \
(bgp->inst_type == BGP_INSTANCE_TYPE_VRF && bgp->vrf_id != VRF_UNKNOWN))
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT \
|| (bgp->inst_type == BGP_INSTANCE_TYPE_VRF \
&& bgp->vrf_id != VRF_UNKNOWN))
/* BGP peer-group support. */
struct peer_group
{
struct peer_group {
/* Name of the peer-group. */
char *name;
@ -397,8 +418,7 @@ struct peer_group
};
/* BGP Notify message format. */
struct bgp_notify
{
struct bgp_notify {
u_char code;
u_char subcode;
char *data;
@ -407,8 +427,7 @@ struct bgp_notify
};
/* Next hop self address. */
struct bgp_nexthop
{
struct bgp_nexthop {
struct interface *ifp;
struct in_addr v4;
struct in6_addr v6_global;
@ -425,8 +444,7 @@ struct bgp_nexthop
/* BGP router distinguisher value. */
#define BGP_RD_SIZE 8
struct bgp_rd
{
struct bgp_rd {
u_char val[BGP_RD_SIZE];
};
@ -437,39 +455,33 @@ struct bgp_rd
#include "filter.h"
/* BGP filter structure. */
struct bgp_filter
{
struct bgp_filter {
/* Distribute-list. */
struct
{
struct {
char *name;
struct access_list *alist;
} dlist[FILTER_MAX];
/* Prefix-list. */
struct
{
struct {
char *name;
struct prefix_list *plist;
} plist[FILTER_MAX];
/* Filter-list. */
struct
{
struct {
char *name;
struct as_list *aslist;
} aslist[FILTER_MAX];
/* Route-map. */
struct
{
struct {
char *name;
struct route_map *map;
} map[RMAP_MAX];
/* Unsuppress-map. */
struct
{
struct {
char *name;
struct route_map *map;
} usmap;
@ -477,8 +489,7 @@ struct bgp_filter
/* IBGP/EBGP identifier. We also have a CONFED peer, which is to say,
a peer who's AS is part of our Confederation. */
typedef enum
{
typedef enum {
BGP_PEER_IBGP = 1,
BGP_PEER_EBGP,
BGP_PEER_INTERNAL,
@ -497,8 +508,7 @@ typedef enum
#define BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS 100
#define BGP_ANNOUNCE_ROUTE_DELAY_MS 500
struct peer_af
{
struct peer_af {
/* back pointer to the peer */
struct peer *peer;
@ -524,8 +534,7 @@ struct peer_af
};
/* BGP neighbor structure. */
struct peer
{
struct peer {
/* BGP structure. */
struct bgp *bgp;
@ -598,6 +607,8 @@ struct peer
unsigned short port; /* Destination port for peer */
char *host; /* Printable address of the peer. */
union sockunion su; /* Sockunion address of the peer. */
/* $FRR indent$ */
/* clang-format off */
#define BGP_PEER_SU_UNSPEC(peer) (peer->su.sa.sa_family == AF_UNSPEC)
time_t uptime; /* Last Up/Down time */
time_t readtime; /* Last read time */
@ -719,8 +730,7 @@ struct peer
char *password;
/* default-originate route-map. */
struct
{
struct {
char *name;
struct route_map *map;
} default_rmap[AFI_MAX][SAFI_MAX];
@ -799,7 +809,8 @@ struct peer
u_int32_t dropped; /* Dropped */
/* Update delay related fields */
u_char update_delay_over; /* When this is set, BGP is no more waiting for EOR */
u_char update_delay_over; /* When this is set, BGP is no more waiting
for EOR */
/* Syncronization list and time. */
struct bgp_synchronize *sync[AFI_MAX][SAFI_MAX];
@ -909,8 +920,7 @@ DECLARE_QOBJ_TYPE(peer)
/* This structure's member directly points incoming packet data
stream. */
struct bgp_nlri
{
struct bgp_nlri {
/* AFI. */
afi_t afi;
@ -1100,8 +1110,7 @@ struct bgp_nlri
#define BGP_DYNAMIC_NEIGHBORS_LIMIT_MAX 5000
/* Flag for peer_clear_soft(). */
enum bgp_clear_type
{
enum bgp_clear_type {
BGP_CLEAR_SOFT_NONE,
BGP_CLEAR_SOFT_OUT,
BGP_CLEAR_SOFT_IN,
@ -1151,12 +1160,12 @@ enum bgp_clear_type
#define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -32
#define BGP_ERR_MAX -33
#define BGP_ERR_INVALID_FOR_DIRECT_PEER -34
#define BGP_ERR_PEER_SAFI_CONFLICT -35
/*
* Enumeration of different policy kinds a peer can be configured with.
*/
typedef enum
{
typedef enum {
BGP_POLICY_ROUTE_MAP,
BGP_POLICY_FILTER_LIST,
BGP_POLICY_PREFIX_LIST,
@ -1185,11 +1194,13 @@ extern int peer_group_listen_range_del(struct peer_group *, struct prefix *);
extern struct peer_group *peer_group_lookup(struct bgp *, const char *);
extern struct peer_group *peer_group_get(struct bgp *, const char *);
extern struct peer *peer_create_bind_dynamic_neighbor(struct bgp *,
union sockunion *, struct peer_group *);
extern struct prefix *peer_group_lookup_dynamic_neighbor_range (
struct peer_group *, struct prefix *);
union sockunion *,
struct peer_group *);
extern struct prefix *
peer_group_lookup_dynamic_neighbor_range(struct peer_group *, struct prefix *);
extern struct peer_group *peer_group_lookup_dynamic_neighbor(struct bgp *,
struct prefix *, struct prefix **);
struct prefix *,
struct prefix **);
extern struct peer *peer_lookup_dynamic_neighbor(struct bgp *,
union sockunion *);
extern void peer_drop_dynamic_neighbor(struct peer *);
@ -1209,7 +1220,8 @@ extern int peer_active (struct peer *);
extern int peer_active_nego(struct peer *);
extern void bgp_recalculate_all_bestpaths(struct bgp *bgp);
extern struct peer *peer_create(union sockunion *, const char *, struct bgp *,
as_t, as_t, int, afi_t, safi_t, struct peer_group *);
as_t, as_t, int, afi_t, safi_t,
struct peer_group *);
extern struct peer *peer_create_accept(struct bgp *);
extern void peer_xfer_config(struct peer *dst, struct peer *src);
extern char *peer_uptime(time_t, char *, size_t, u_char, json_object *);
@ -1252,7 +1264,8 @@ extern int bgp_confederation_peers_check (struct bgp *, as_t);
extern int bgp_confederation_peers_add(struct bgp *, as_t);
extern int bgp_confederation_peers_remove(struct bgp *, as_t);
extern int bgp_timers_set (struct bgp *, u_int32_t keepalive, u_int32_t holdtime);
extern int bgp_timers_set(struct bgp *, u_int32_t keepalive,
u_int32_t holdtime);
extern int bgp_timers_unset(struct bgp *);
extern int bgp_default_local_preference_set(struct bgp *, u_int32_t);
@ -1301,7 +1314,8 @@ 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 *, afi_t, safi_t,
const char *);
extern int peer_default_originate_unset(struct peer *, afi_t, safi_t);
extern int peer_port_set(struct peer *, u_int16_t);
@ -1310,7 +1324,8 @@ extern int peer_port_unset (struct peer *);
extern int peer_weight_set(struct peer *, afi_t, safi_t, u_int16_t);
extern int peer_weight_unset(struct peer *, afi_t, safi_t);
extern int peer_timers_set (struct peer *, u_int32_t keepalive, u_int32_t holdtime);
extern int peer_timers_set(struct peer *, u_int32_t keepalive,
u_int32_t holdtime);
extern int peer_timers_unset(struct peer *);
extern int peer_timers_connect_set(struct peer *, u_int32_t);
@ -1331,7 +1346,8 @@ extern int peer_allowas_in_unset (struct peer *, afi_t, safi_t);
extern int peer_local_as_set(struct peer *, as_t, int, int);
extern int peer_local_as_unset(struct peer *);
extern int peer_prefix_list_set (struct peer *, afi_t, safi_t, int, const char *);
extern int peer_prefix_list_set(struct peer *, afi_t, safi_t, int,
const char *);
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 *);
@ -1347,7 +1363,8 @@ extern int peer_password_unset (struct peer *);
extern int peer_unsuppress_map_unset(struct peer *, afi_t, safi_t);
extern int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, u_char, int, u_int16_t);
extern int peer_maximum_prefix_set(struct peer *, afi_t, safi_t, u_int32_t,
u_char, int, u_int16_t);
extern int peer_maximum_prefix_unset(struct peer *, afi_t, safi_t);
extern int peer_clear(struct peer *, struct listnode **);
@ -1364,11 +1381,9 @@ extern void bgp_route_map_terminate(void);
extern int peer_cmp(struct peer *p1, struct peer *p2);
extern int
bgp_map_afi_safi_iana2int (iana_afi_t pkt_afi, safi_t pkt_safi,
extern int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, safi_t pkt_safi,
afi_t *afi, safi_t *safi);
extern int
bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi,
extern int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi,
iana_afi_t *pkt_afi, safi_t *pkt_safi);
extern struct peer_af *peer_af_create(struct peer *, afi_t, safi_t);
@ -1377,14 +1392,11 @@ extern int peer_af_delete (struct peer *, afi_t, safi_t);
extern void bgp_close(void);
static inline int
afindex (afi_t afi, safi_t safi)
{
switch (afi)
static inline int afindex(afi_t afi, safi_t safi)
{
switch (afi) {
case AFI_IP:
switch (safi)
{
switch (safi) {
case SAFI_UNICAST:
return BGP_AF_IPV4_UNICAST;
break;
@ -1406,8 +1418,7 @@ afindex (afi_t afi, safi_t safi)
}
break;
case AFI_IP6:
switch (safi)
{
switch (safi) {
case SAFI_UNICAST:
return BGP_AF_IPV6_UNICAST;
break;
@ -1429,8 +1440,7 @@ afindex (afi_t afi, safi_t safi)
}
break;
case AFI_L2VPN:
switch (safi)
{
switch (safi) {
case SAFI_EVPN:
return BGP_AF_L2VPN_EVPN;
break;
@ -1445,8 +1455,7 @@ afindex (afi_t afi, safi_t safi)
}
/* If the peer is not a peer-group but is bound to a peer-group return 1 */
static inline int
peer_group_active (struct peer *peer)
static inline int peer_group_active(struct peer *peer)
{
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) && peer->group)
return 1;
@ -1454,69 +1463,61 @@ peer_group_active (struct peer *peer)
}
/* If peer is negotiated at least one address family return 1. */
static inline int
peer_afi_active_nego (const struct peer *peer, afi_t afi)
static inline int peer_afi_active_nego(const struct peer *peer, afi_t afi)
{
if (peer->afc_nego[afi][SAFI_UNICAST]
|| peer->afc_nego[afi][SAFI_MULTICAST]
|| peer->afc_nego[afi][SAFI_LABELED_UNICAST]
|| peer->afc_nego[afi][SAFI_MPLS_VPN]
|| peer->afc_nego[afi][SAFI_ENCAP])
|| peer->afc_nego[afi][SAFI_ENCAP]
|| peer->afc_nego[afi][SAFI_EVPN])
return 1;
return 0;
}
/* If at least one address family activated for group, return 1. */
static inline int
peer_group_af_configured (struct peer_group *group)
static inline int peer_group_af_configured(struct peer_group *group)
{
struct peer *peer = group->conf;
if (peer->afc[AFI_IP][SAFI_UNICAST]
|| peer->afc[AFI_IP][SAFI_MULTICAST]
if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
|| peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP][SAFI_ENCAP]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
|| peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_ENCAP])
|| peer->afc[AFI_IP6][SAFI_ENCAP] || peer->afc[AFI_IP6][SAFI_EVPN])
return 1;
return 0;
}
static inline char *
timestamp_string (time_t ts)
static inline char *timestamp_string(time_t ts)
{
time_t tbuf;
tbuf = time(NULL) - (bgp_clock() - ts);
return ctime(&tbuf);
}
static inline int
peer_established (struct peer *peer)
static inline int peer_established(struct peer *peer)
{
if (peer->status == Established)
return 1;
return 0;
}
static inline int
peer_dynamic_neighbor (struct peer *peer)
static inline int peer_dynamic_neighbor(struct peer *peer)
{
return (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR)) ? 1 : 0;
}
static inline int
peer_cap_enhe (struct peer *peer, afi_t afi, safi_t safi)
static inline int peer_cap_enhe(struct peer *peer, afi_t afi, safi_t safi)
{
return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_NEGO));
}
/* Lookup VRF for BGP instance based on its type. */
static inline struct vrf *
bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
static inline struct vrf *bgp_vrf_lookup_by_instance_type(struct bgp *bgp)
{
struct vrf *vrf;
@ -1531,23 +1532,19 @@ bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
}
/* Link BGP instance to VRF. */
static inline void
bgp_vrf_link (struct bgp *bgp, struct vrf *vrf)
static inline void bgp_vrf_link(struct bgp *bgp, struct vrf *vrf)
{
bgp->vrf_id = vrf->vrf_id;
if (vrf->info != (void *)bgp)
{
if (vrf->info != (void *)bgp) {
bgp_lock(bgp);
vrf->info = (void *)bgp;
}
}
/* Unlink BGP instance from VRF. */
static inline void
bgp_vrf_unlink (struct bgp *bgp, struct vrf *vrf)
{
if (vrf->info == (void *)bgp)
static inline void bgp_vrf_unlink(struct bgp *bgp, struct vrf *vrf)
{
if (vrf->info == (void *)bgp) {
vrf->info = NULL;
bgp_unlock(bgp);
}

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,7 @@
#if ENABLE_BGP_VNC
#include "rfapi.h"
struct rfapi_l2_group_cfg
{
struct rfapi_l2_group_cfg {
char *name;
uint32_t logical_net_id;
struct list *labels; /* list of uint32_t */
@ -40,16 +39,14 @@ struct rfapi_l2_group_cfg
};
DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg)
typedef enum
{
typedef enum {
RFAPI_GROUP_CFG_NVE = 1,
RFAPI_GROUP_CFG_VRF,
RFAPI_GROUP_CFG_L2,
RFAPI_GROUP_CFG_MAX
} rfapi_group_cfg_type_t;
struct rfapi_nve_group_cfg
{
struct rfapi_nve_group_cfg {
struct route_node *vn_node; /* backref */
struct route_node *un_node; /* backref */
@ -115,21 +112,18 @@ struct rfapi_nve_group_cfg
};
DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg)
struct rfapi_rfg_name
{
struct rfapi_rfg_name {
struct rfapi_nve_group_cfg *rfg;
char *name;
};
typedef enum
{
typedef enum {
VNC_REDIST_MODE_PLAIN = 0, /* 0 = default */
VNC_REDIST_MODE_RFG,
VNC_REDIST_MODE_RESOLVE_NVE
} vnc_redist_mode_t;
struct rfapi_cfg
{
struct rfapi_cfg {
struct prefix_rd default_rd;
uint8_t default_l2rd;
struct ecommunity *default_rt_import_list;
@ -169,7 +163,8 @@ struct rfapi_cfg
/*
* List of NVE groups on whose behalf we will export VNC
* routes to zebra. ((NB: it's actually a list of <struct rfapi_rfg_name>)
* routes to zebra. ((NB: it's actually a list of <struct
* rfapi_rfg_name>)
* This list is used when BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS is
* BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP
*/
@ -245,96 +240,74 @@ struct rfapi_cfg
/* Default to updated-responses off */
/* Default to removal-responses off */
#define BGP_VNC_CONFIG_FLAGS_DEFAULT \
(BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP |\
BGP_VNC_CONFIG_CALLBACK_DISABLE |\
BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)
(BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP | BGP_VNC_CONFIG_CALLBACK_DISABLE \
| BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)
struct rfapi_rfp_cfg rfp_cfg; /* rfp related configuration */
};
#define VNC_EXPORT_ZEBRA_GRP_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP)
#define VNC_EXPORT_ZEBRA_RH_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH)
#define VNC_EXPORT_BGP_GRP_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP)
#define VNC_EXPORT_BGP_RH_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH)
#define VNC_EXPORT_BGP_CE_ENABLED(hc) \
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE)
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \
== BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE)
void
bgp_rfapi_cfg_init (void);
void bgp_rfapi_cfg_init(void);
struct rfapi_cfg *
bgp_rfapi_cfg_new (struct rfapi_rfp_cfg *cfg);
struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg);
void
bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h);
void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h);
int
bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp);
int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp);
extern int
bgp_rfapi_is_vnc_configured (struct bgp *bgp);
extern int bgp_rfapi_is_vnc_configured(struct bgp *bgp);
extern void
nve_group_to_nve_list (
struct rfapi_nve_group_cfg *rfg,
extern void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg,
struct list **nves,
uint8_t family); /* AF_INET, AF_INET6 */
struct rfapi_nve_group_cfg *
bgp_rfapi_cfg_match_group (
struct rfapi_cfg *hc,
struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
struct prefix *vn,
struct prefix *un);
struct rfapi_nve_group_cfg *
bgp_rfapi_cfg_match_byname (
struct bgp *bgp,
const char *name,
bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name,
rfapi_group_cfg_type_t type); /* _MAX = any */
extern void
vnc_prefix_list_update (struct bgp *bgp);
extern void vnc_prefix_list_update(struct bgp *bgp);
extern void
vnc_routemap_update (struct bgp *bgp, const char *unused);
extern void vnc_routemap_update(struct bgp *bgp, const char *unused);
extern void
bgp_rfapi_show_summary (struct bgp *bgp, struct vty *vty);
extern void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty);
extern struct rfapi_cfg *
bgp_rfapi_get_config (struct bgp *bgp);
extern struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp);
extern struct rfapi_l2_group_cfg *
bgp_rfapi_get_group_by_lni_label (
struct bgp *bgp,
uint32_t logical_net_id,
bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id,
uint32_t label);
extern struct ecommunity *
bgp_rfapi_get_ecommunity_by_lni_label (
struct bgp *bgp,
uint32_t is_import,
bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import,
uint32_t logical_net_id,
uint32_t label); /* note, 20bit label! */
extern struct list *
bgp_rfapi_get_labellist_by_lni_label (
struct bgp *bgp,
uint32_t logical_net_id,
bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp, uint32_t logical_net_id,
uint32_t label); /* note, 20bit label! */
#endif /* ENABLE_BGP_VNC */

File diff suppressed because it is too large Load Diff

View File

@ -44,31 +44,26 @@
#define RFAPI_V6_ADDR 0x06
#define RFAPI_SHOW_STR "VNC information\n"
struct rfapi_ip_addr
{
struct rfapi_ip_addr {
uint8_t addr_family; /* AF_INET | AF_INET6 */
union
{
union {
struct in_addr v4; /* in network order */
struct in6_addr v6; /* in network order */
} addr;
};
struct rfapi_ip_prefix
{
struct rfapi_ip_prefix {
uint8_t length;
uint8_t cost; /* bgp local pref = 255 - cost */
struct rfapi_ip_addr prefix;
};
struct rfapi_nexthop
{
struct rfapi_nexthop {
struct prefix addr;
uint8_t cost;
};
struct rfapi_next_hop_entry
{
struct rfapi_next_hop_entry {
struct rfapi_next_hop_entry *next;
struct rfapi_ip_prefix prefix;
uint32_t lifetime;
@ -81,8 +76,7 @@ struct rfapi_next_hop_entry
#define RFAPI_REMOVE_RESPONSE_LIFETIME 0
#define RFAPI_INFINITE_LIFETIME 0xFFFFFFFF
struct rfapi_l2address_option
{
struct rfapi_l2address_option {
struct ethaddr macaddr; /* use 0 to assign label to IP prefix */
uint32_t label; /* 20bit label in low bits, no TC, S, or TTL */
uint32_t logical_net_id; /* ~= EVPN Ethernet Segment Id,
@ -91,24 +85,24 @@ struct rfapi_l2address_option
uint16_t tag_id; /* EVPN Ethernet Tag ID, 0 = none */
};
typedef enum
{
typedef enum {
RFAPI_UN_OPTION_TYPE_PROVISIONAL, /* internal use only */
RFAPI_UN_OPTION_TYPE_TUNNELTYPE,
} rfapi_un_option_type;
struct rfapi_tunneltype_option
{
struct rfapi_tunneltype_option {
bgp_encap_types type;
union
{
union {
struct bgp_encap_type_reserved reserved;
struct bgp_encap_type_l2tpv3_over_ip l2tpv3_ip;
struct bgp_encap_type_gre gre;
struct bgp_encap_type_transmit_tunnel_endpoint transmit_tunnel_endpoint;
struct bgp_encap_type_transmit_tunnel_endpoint
transmit_tunnel_endpoint;
struct bgp_encap_type_ipsec_in_tunnel_mode ipsec_tunnel;
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode ip_ipsec;
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode mpls_ipsec;
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode
ip_ipsec;
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode
mpls_ipsec;
struct bgp_encap_type_ip_in_ip ip_ip;
struct bgp_encap_type_vxlan vxlan;
struct bgp_encap_type_nvgre nvgre;
@ -120,31 +114,27 @@ struct rfapi_tunneltype_option
} bgpinfo;
};
struct rfapi_un_option
{
struct rfapi_un_option {
struct rfapi_un_option *next;
rfapi_un_option_type type;
union
{
union {
struct rfapi_tunneltype_option tunnel;
} v;
};
typedef enum
{
RFAPI_VN_OPTION_TYPE_L2ADDR = 3, /* Layer 2 address, 3 for legacy compatibility */
typedef enum {
RFAPI_VN_OPTION_TYPE_L2ADDR =
3, /* Layer 2 address, 3 for legacy compatibility */
RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP, /* for static routes */
RFAPI_VN_OPTION_TYPE_INTERNAL_RD, /* internal use only */
} rfapi_vn_option_type;
struct rfapi_vn_option
{
struct rfapi_vn_option {
struct rfapi_vn_option *next;
rfapi_vn_option_type type;
union
{
union {
struct rfapi_l2address_option l2addr;
/*
@ -160,8 +150,7 @@ struct rfapi_vn_option
} v;
};
struct rfapi_l2address_option_match
{
struct rfapi_l2address_option_match {
struct rfapi_l2address_option o;
uint32_t flags;
@ -269,31 +258,26 @@ typedef int (rfp_cfg_write_cb_t) (struct vty * vty, void *rfp_start_val);
* return value:
* lines written
--------------------------------------------*/
typedef enum
{
typedef enum {
RFAPI_RFP_CFG_GROUP_DEFAULT,
RFAPI_RFP_CFG_GROUP_NVE,
RFAPI_RFP_CFG_GROUP_L2
} rfapi_rfp_cfg_group_type;
typedef int (rfp_cfg_group_write_cb_t) (struct vty * vty,
void *rfp_start_val,
typedef int(rfp_cfg_group_write_cb_t)(struct vty *vty, void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
const char *name,
void *rfp_cfg_group);
const char *name, void *rfp_cfg_group);
/***********************************************************************
* Configuration related defines and structures
***********************************************************************/
struct rfapi_rfp_cb_methods
{
struct rfapi_rfp_cb_methods {
rfp_cfg_write_cb_t *cfg_cb; /* show top level config */
rfp_cfg_group_write_cb_t *cfg_group_cb; /* show group level config */
rfapi_response_cb_t *response_cb; /* unsolicited responses */
rfapi_response_cb_t *local_cb; /* local route add/delete */
rfapi_nve_close_cb_t *close_cb; /* handle closed */
};
/*
@ -319,16 +303,14 @@ struct rfapi_rfp_cb_methods
* rfapi_query. When partial table download is used, only
* information matching a query is passed.
*/
typedef enum
{
typedef enum {
RFAPI_RFP_DOWNLOAD_PARTIAL = 0,
RFAPI_RFP_DOWNLOAD_FULL
} rfapi_rfp_download_type;
#define RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL 1
struct rfapi_rfp_cfg
{
struct rfapi_rfp_cfg {
/* partial or full table download */
rfapi_rfp_download_type download_type; /* default=partial */
/*
@ -370,9 +352,7 @@ struct rfapi_rfp_cfg
* return value:
* rfp_start_val rfp returned value passed on rfp_stop and other rfapi calls
--------------------------------------------*/
extern void *
rfp_start (
struct thread_master *master,
extern void *rfp_start(struct thread_master *master,
struct rfapi_rfp_cfg **cfgp,
struct rfapi_rfp_cb_methods **cbmp);
@ -389,8 +369,7 @@ rfp_start (
*
* return value:
--------------------------------------------*/
extern void
rfp_stop (void *rfp_start_val);
extern void rfp_stop(void *rfp_start_val);
/***********************************************************************
* RFP processing behavior configuration
@ -413,9 +392,7 @@ rfp_stop (void *rfp_start_val);
* 0 Success
* ENXIO Unabled to locate configured BGP/VNC
--------------------------------------------*/
extern int
rfapi_rfp_set_configuration (
void *rfp_start_val,
extern int rfapi_rfp_set_configuration(void *rfp_start_val,
struct rfapi_rfp_cfg *rfp_cfg);
/*------------------------------------------
@ -433,9 +410,7 @@ rfapi_rfp_set_configuration (
* 0 Success
* ENXIO BGP or VNC not configured
*------------------------------------------*/
extern int
rfapi_rfp_set_cb_methods (
void *rfp_start_val,
extern int rfapi_rfp_set_cb_methods(void *rfp_start_val,
struct rfapi_rfp_cb_methods *methods);
/***********************************************************************
@ -463,9 +438,7 @@ rfapi_rfp_set_cb_methods (
* return value:
* rfp_cfg_group NULL or Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_init_group_config_ptr_vty (
void *rfp_start_val,
extern void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
struct vty *vty,
uint32_t size);
@ -489,9 +462,7 @@ rfapi_rfp_init_group_config_ptr_vty (
* return value:
* rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_get_group_config_ptr_vty (
void *rfp_start_val,
extern void *rfapi_rfp_get_group_config_ptr_vty(void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
struct vty *vty);
@ -512,8 +483,7 @@ rfapi_rfp_get_group_config_ptr_vty (
* 0 Match/Success
* ENOENT No matching
--------------------------------------------*/
typedef int (rfp_group_config_search_cb_t) (void *criteria,
void *rfp_cfg_group);
typedef int(rfp_group_config_search_cb_t)(void *criteria, void *rfp_cfg_group);
/*------------------------------------------
* rfapi_rfp_get_group_config_ptr_name
@ -536,13 +506,9 @@ typedef int (rfp_group_config_search_cb_t) (void *criteria,
* return value:
* rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_get_group_config_ptr_name (
void *rfp_start_val,
rfapi_rfp_cfg_group_type type,
const char *name,
void *criteria,
rfp_group_config_search_cb_t *search_cb);
extern void *rfapi_rfp_get_group_config_ptr_name(
void *rfp_start_val, rfapi_rfp_cfg_group_type type, const char *name,
void *criteria, rfp_group_config_search_cb_t *search_cb);
/*------------------------------------------
* rfapi_rfp_get_l2_group_config_ptr_lni
@ -565,10 +531,8 @@ rfapi_rfp_get_group_config_ptr_name (
* rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
extern void *
rfapi_rfp_get_l2_group_config_ptr_lni (
void *rfp_start_val,
uint32_t logical_net_id,
void *criteria,
rfapi_rfp_get_l2_group_config_ptr_lni(void *rfp_start_val,
uint32_t logical_net_id, void *criteria,
rfp_group_config_search_cb_t *search_cb);
/***********************************************************************
@ -615,14 +579,10 @@ rfapi_rfp_get_l2_group_config_ptr_lni (
* but underlay network address is not IPv4
* EDEADLK Called from within a callback procedure
*------------------------------------------*/
extern int
rfapi_open (
void *rfp_start_val,
struct rfapi_ip_addr *vn,
extern int rfapi_open(void *rfp_start_val, struct rfapi_ip_addr *vn,
struct rfapi_ip_addr *un,
struct rfapi_un_option *default_options,
uint32_t *response_lifetime,
void *userdata,
uint32_t *response_lifetime, void *userdata,
rfapi_handle *pHandle);
@ -643,8 +603,7 @@ rfapi_open (
* EBADF invalid handle
* ENXIO BGP or VNC not configured
*------------------------------------------*/
extern int
rfapi_close (rfapi_handle rfd);
extern int rfapi_close(rfapi_handle rfd);
/*------------------------------------------
* rfapi_check
@ -664,8 +623,7 @@ rfapi_close (rfapi_handle rfd);
* ENXIO BGP or VNC not configured
* EAFNOSUPPORT Internal addressing error
*------------------------------------------*/
extern int
rfapi_check (rfapi_handle rfd);
extern int rfapi_check(rfapi_handle rfd);
/***********************************************************************
* NVE Routes
@ -701,10 +659,7 @@ rfapi_check (rfapi_handle rfd);
* ESTALE descriptor is no longer usable; should be closed
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
extern int
rfapi_query (
rfapi_handle rfd,
struct rfapi_ip_addr *target,
extern int rfapi_query(rfapi_handle rfd, struct rfapi_ip_addr *target,
struct rfapi_l2address_option *l2o,
struct rfapi_next_hop_entry **ppNextHopEntry);
@ -728,8 +683,7 @@ rfapi_query (
* ESTALE descriptor is no longer usable; should be closed
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
extern int
rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target);
extern int rfapi_query_done(rfapi_handle rfd, struct rfapi_ip_addr *target);
/*------------------------------------------
* rfapi_query_done_all
@ -750,8 +704,7 @@ rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target);
* ESTALE descriptor is no longer usable; should be closed
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
extern int
rfapi_query_done_all (rfapi_handle rfd, int *count);
extern int rfapi_query_done_all(rfapi_handle rfd, int *count);
/*------------------------------------------
* rfapi_register
@ -785,19 +738,14 @@ rfapi_query_done_all (rfapi_handle rfd, int *count);
* EDEADLK Called from within a callback procedure
--------------------------------------------*/
typedef enum
{
typedef enum {
RFAPI_REGISTER_ADD,
RFAPI_REGISTER_WITHDRAW,
RFAPI_REGISTER_KILL
} rfapi_register_action;
extern int
rfapi_register (
rfapi_handle rfd,
struct rfapi_ip_prefix *prefix,
uint32_t lifetime,
struct rfapi_un_option *options_un,
extern int rfapi_register(rfapi_handle rfd, struct rfapi_ip_prefix *prefix,
uint32_t lifetime, struct rfapi_un_option *options_un,
struct rfapi_vn_option *options_vn,
rfapi_register_action action);
@ -818,8 +766,7 @@ rfapi_register (
* return value:
* vn NVE virtual network address
*------------------------------------------*/
extern struct rfapi_ip_addr *
rfapi_get_vn_addr (void *);
extern struct rfapi_ip_addr *rfapi_get_vn_addr(void *);
/*------------------------------------------
* rfapi_get_un_addr
@ -834,8 +781,7 @@ rfapi_get_vn_addr (void *);
* return value:
* un NVE underlay network address
*------------------------------------------*/
extern struct rfapi_ip_addr *
rfapi_get_un_addr (void *);
extern struct rfapi_ip_addr *rfapi_get_un_addr(void *);
/*------------------------------------------
* rfapi_error_str
@ -850,8 +796,7 @@ rfapi_get_un_addr (void *);
*
* const char * String
*------------------------------------------*/
extern const char *
rfapi_error_str (int code);
extern const char *rfapi_error_str(int code);
/*------------------------------------------
* rfapi_get_rfp_start_val
@ -864,8 +809,7 @@ rfapi_error_str (int code);
* returns:
* void *
*------------------------------------------*/
extern void *
rfapi_get_rfp_start_val (void *bgpv);
extern void *rfapi_get_rfp_start_val(void *bgpv);
/*------------------------------------------
* rfapi_compare_rfds
@ -882,8 +826,7 @@ rfapi_get_rfp_start_val (void *bgpv);
* 0 Mismatch
* 1 Match
*------------------------------------------*/
extern int
rfapi_compare_rfds (void *rfd1, void *rfd2);
extern int rfapi_compare_rfds(void *rfd1, void *rfd2);
/*------------------------------------------
* rfapi_free_next_hop_list
@ -898,8 +841,7 @@ rfapi_compare_rfds (void *rfd1, void *rfd2);
*
* return value: None
--------------------------------------------*/
extern void
rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list);
extern void rfapi_free_next_hop_list(struct rfapi_next_hop_entry *list);
/*------------------------------------------
* rfapi_get_response_lifetime_default
@ -915,8 +857,7 @@ rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list);
*
* return value: The bgp instance default lifetime for a response.
--------------------------------------------*/
extern int
rfapi_get_response_lifetime_default (void *rfp_start_val);
extern int rfapi_get_response_lifetime_default(void *rfp_start_val);
/*------------------------------------------
* rfapi_is_vnc_configured
@ -933,8 +874,7 @@ rfapi_get_response_lifetime_default (void *rfp_start_val);
* 0 Success
* ENXIO VNC not configured
--------------------------------------------*/
extern int
rfapi_is_vnc_configured (void *rfp_start_val);
extern int rfapi_is_vnc_configured(void *rfp_start_val);
/*------------------------------------------
* rfapi_bgp_lookup_by_rfp
@ -953,8 +893,7 @@ rfapi_is_vnc_configured (void *rfp_start_val);
* NULL = not found
*
--------------------------------------------*/
extern struct bgp *
rfapi_bgp_lookup_by_rfp (void *rfp_start_val);
extern struct bgp *rfapi_bgp_lookup_by_rfp(void *rfp_start_val);
/*------------------------------------------
* rfapi_get_rfp_start_val_by_bgp
@ -972,8 +911,7 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val);
* NULL = not found
*
--------------------------------------------*/
extern void *
rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp);
extern void *rfapi_get_rfp_start_val_by_bgp(struct bgp *bgp);
#endif /* ENABLE_BGP_VNC */

View File

@ -83,8 +83,7 @@
* is used to spread out the sort for adbs with the same lifetime
* and thereby make the skip list operations more efficient.
*/
static int
sl_adb_lifetime_cmp (void *adb1, void *adb2)
static int sl_adb_lifetime_cmp(void *adb1, void *adb2)
{
struct rfapi_adb *a1 = adb1;
struct rfapi_adb *a2 = adb2;
@ -102,28 +101,27 @@ sl_adb_lifetime_cmp (void *adb1, void *adb2)
return 0;
}
void
rfapiApInit (struct rfapi_advertised_prefixes *ap)
void rfapiApInit(struct rfapi_advertised_prefixes *ap)
{
ap->ipN_by_prefix = skiplist_new(0, rfapi_rib_key_cmp, NULL);
ap->ip0_by_ether = skiplist_new(0, rfapi_rib_key_cmp, NULL);
ap->by_lifetime = skiplist_new(0, sl_adb_lifetime_cmp, NULL);
}
void
rfapiApRelease (struct rfapi_advertised_prefixes *ap)
void rfapiApRelease(struct rfapi_advertised_prefixes *ap)
{
struct rfapi_adb *adb;
/* Free ADBs and lifetime items */
while (0 == skiplist_first (ap->by_lifetime, NULL, (void **) &adb))
{
while (0 == skiplist_first(ap->by_lifetime, NULL, (void **)&adb)) {
rfapiAdbFree(adb);
skiplist_delete_first(ap->by_lifetime);
}
while (0 == skiplist_delete_first (ap->ipN_by_prefix));
while (0 == skiplist_delete_first (ap->ip0_by_ether));
while (0 == skiplist_delete_first(ap->ipN_by_prefix))
;
while (0 == skiplist_delete_first(ap->ip0_by_ether))
;
/* Free lists */
skiplist_free(ap->ipN_by_prefix);
@ -135,8 +133,7 @@ rfapiApRelease (struct rfapi_advertised_prefixes *ap)
ap->by_lifetime = NULL;
}
int
rfapiApCount (struct rfapi_descriptor *rfd)
int rfapiApCount(struct rfapi_descriptor *rfd)
{
if (!rfd->advertised.by_lifetime)
return 0;
@ -144,8 +141,7 @@ rfapiApCount (struct rfapi_descriptor *rfd)
return skiplist_count(rfd->advertised.by_lifetime);
}
int
rfapiApCountAll (struct bgp *bgp)
int rfapiApCountAll(struct bgp *bgp)
{
struct rfapi *h;
struct listnode *node;
@ -153,10 +149,8 @@ rfapiApCountAll (struct bgp *bgp)
int total = 0;
h = bgp->rfapi;
if (h)
{
for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
{
if (h) {
for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
total += rfapiApCount(rfd);
}
}
@ -164,20 +158,16 @@ rfapiApCountAll (struct bgp *bgp)
}
void
rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
void rfapiApReadvertiseAll(struct bgp *bgp, struct rfapi_descriptor *rfd)
{
struct rfapi_adb *adb;
void *cursor = NULL;
int rc;
for (rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor); rc == 0;
rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor))
{
for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor);
rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor)) {
struct prefix_rd prd;
uint32_t local_pref = rfp_cost_to_localpref(adb->cost);
@ -190,17 +180,18 @@ rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
* TBD this is not quite right. When pfx_ip is 0/32 or 0/128,
* we need to substitute the VN address as the prefix
*/
add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, &prd, /* RD to use (0 for ENCAP) */
add_vnc_route(rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip,
&prd, /* RD to use (0 for ENCAP) */
&rfd->vn_addr, /* nexthop */
&local_pref, &adb->lifetime, NULL, NULL, /* struct rfapi_un_option */
&local_pref, &adb->lifetime, NULL,
NULL, /* struct rfapi_un_option */
NULL, /* struct rfapi_vn_option */
rfd->rt_export_list, NULL, /* med */
NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0);
}
}
void
rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd)
{
struct rfapi_adb *adb;
void *cursor;
@ -208,44 +199,40 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
cursor = NULL;
for (rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor); rc == 0;
rc =
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
&cursor))
{
for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor);
rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL,
(void **)&adb, &cursor)) {
struct prefix pfx_vn_buf;
struct prefix *pfx_ip;
if (!(RFAPI_0_PREFIX (&adb->u.s.prefix_ip) &&
RFAPI_HOST_PREFIX (&adb->u.s.prefix_ip)))
{
if (!(RFAPI_0_PREFIX(&adb->u.s.prefix_ip)
&& RFAPI_HOST_PREFIX(&adb->u.s.prefix_ip))) {
pfx_ip = &adb->u.s.prefix_ip;
}
else
{
} else {
pfx_ip = NULL;
/*
* 0/32 or 0/128 => mac advertisement
*/
if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf))
{
if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) {
/*
* Bad: it means we can't delete the route
*/
vnc_zlog_debug_verbose ("%s: BAD: handle has bad vn_addr: skipping",
vnc_zlog_debug_verbose(
"%s: BAD: handle has bad vn_addr: skipping",
__func__);
continue;
}
}
del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->u.s.prd, /* RD to use (0 for ENCAP) */
del_vnc_route(rfd, rfd->peer, bgp, SAFI_MPLS_VPN,
pfx_ip ? pfx_ip : &pfx_vn_buf,
&adb->u.s.prd, /* RD to use (0 for ENCAP) */
ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0);
}
}
@ -253,8 +240,7 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
/*
* returns nonzero if tunnel readvertisement is needed, 0 otherwise
*/
static int
rfapiApAdjustLifetimeStats (
static int rfapiApAdjustLifetimeStats(
struct rfapi_descriptor *rfd,
uint32_t *old_lifetime, /* set if removing/replacing */
uint32_t *new_lifetime) /* set if replacing/adding */
@ -263,20 +249,20 @@ rfapiApAdjustLifetimeStats (
int find_max = 0;
int find_min = 0;
vnc_zlog_debug_verbose ("%s: rfd=%p, pOldLife=%p, pNewLife=%p",
__func__, rfd, old_lifetime, new_lifetime);
vnc_zlog_debug_verbose("%s: rfd=%p, pOldLife=%p, pNewLife=%p", __func__,
rfd, old_lifetime, new_lifetime);
if (old_lifetime)
vnc_zlog_debug_verbose ("%s: OldLife=%d", __func__, *old_lifetime);
vnc_zlog_debug_verbose("%s: OldLife=%d", __func__,
*old_lifetime);
if (new_lifetime)
vnc_zlog_debug_verbose ("%s: NewLife=%d", __func__, *new_lifetime);
vnc_zlog_debug_verbose("%s: NewLife=%d", __func__,
*new_lifetime);
if (new_lifetime)
{
if (new_lifetime) {
/*
* Adding new lifetime
*/
if (old_lifetime)
{
if (old_lifetime) {
/*
* replacing existing lifetime
*/
@ -286,48 +272,38 @@ rfapiApAdjustLifetimeStats (
if (*old_lifetime == *new_lifetime)
return 0;
if (*old_lifetime == rfd->min_prefix_lifetime)
{
if (*old_lifetime == rfd->min_prefix_lifetime) {
find_min = 1;
}
if (*old_lifetime == rfd->max_prefix_lifetime)
{
if (*old_lifetime == rfd->max_prefix_lifetime) {
find_max = 1;
}
/* no need to search if new value is at or equals min|max */
if (*new_lifetime <= rfd->min_prefix_lifetime)
{
/* no need to search if new value is at or equals
* min|max */
if (*new_lifetime <= rfd->min_prefix_lifetime) {
rfd->min_prefix_lifetime = *new_lifetime;
find_min = 0;
}
if (*new_lifetime >= rfd->max_prefix_lifetime)
{
if (*new_lifetime >= rfd->max_prefix_lifetime) {
rfd->max_prefix_lifetime = *new_lifetime;
advertise = 1;
find_max = 0;
}
}
else
{
} else {
/*
* Just adding new lifetime
*/
if (*new_lifetime < rfd->min_prefix_lifetime)
{
if (*new_lifetime < rfd->min_prefix_lifetime) {
rfd->min_prefix_lifetime = *new_lifetime;
}
if (*new_lifetime > rfd->max_prefix_lifetime)
{
if (*new_lifetime > rfd->max_prefix_lifetime) {
advertise = 1;
rfd->max_prefix_lifetime = *new_lifetime;
}
}
}
else
{
} else {
/*
* Deleting
*/
@ -344,8 +320,7 @@ rfapiApAdjustLifetimeStats (
* address family that matches the VN address.
*
*/
if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime)
{
if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) {
/*
* Common case: all lifetimes are the same. Only
@ -353,43 +328,35 @@ rfapiApAdjustLifetimeStats (
* no exported routes left. In that case, reinitialize
* the max and min values.
*/
if (!rfapiApCount (rfd))
{
if (!rfapiApCount(rfd)) {
rfd->max_prefix_lifetime = 0;
rfd->min_prefix_lifetime = UINT32_MAX;
}
}
else
{
if (old_lifetime)
{
if (*old_lifetime == rfd->min_prefix_lifetime)
{
} else {
if (old_lifetime) {
if (*old_lifetime == rfd->min_prefix_lifetime) {
find_min = 1;
}
if (*old_lifetime == rfd->max_prefix_lifetime)
{
if (*old_lifetime == rfd->max_prefix_lifetime) {
find_max = 1;
}
}
}
}
if (find_min || find_max)
{
if (find_min || find_max) {
uint32_t min = UINT32_MAX;
uint32_t max = 0;
struct rfapi_adb *adb_min;
struct rfapi_adb *adb_max;
if (!skiplist_first
(rfd->advertised.by_lifetime, (void **) &adb_min, NULL)
&& !skiplist_last (rfd->advertised.by_lifetime, (void **) &adb_max,
NULL))
{
if (!skiplist_first(rfd->advertised.by_lifetime,
(void **)&adb_min, NULL)
&& !skiplist_last(rfd->advertised.by_lifetime,
(void **)&adb_max, NULL)) {
/*
* This should always work
@ -397,25 +364,24 @@ rfapiApAdjustLifetimeStats (
min = adb_min->lifetime;
max = adb_max->lifetime;
}
else
{
} else {
void *cursor;
struct rfapi_rib_key rk;
struct rfapi_adb *adb;
int rc;
vnc_zlog_debug_verbose ("%s: walking to find new min/max", __func__);
vnc_zlog_debug_verbose(
"%s: walking to find new min/max", __func__);
cursor = NULL;
for (rc = skiplist_next(rfd->advertised.ipN_by_prefix,
(void **)&rk, (void **)&adb,
&cursor); !rc;
rc =
skiplist_next (rfd->advertised.ipN_by_prefix,
(void **) &rk, (void **) &adb, &cursor))
{
&cursor);
!rc;
rc = skiplist_next(rfd->advertised.ipN_by_prefix,
(void **)&rk, (void **)&adb,
&cursor)) {
uint32_t lt = adb->lifetime;
@ -427,11 +393,11 @@ rfapiApAdjustLifetimeStats (
cursor = NULL;
for (rc = skiplist_next(rfd->advertised.ip0_by_ether,
(void **)&rk, (void **)&adb,
&cursor); !rc;
rc =
skiplist_next (rfd->advertised.ip0_by_ether, (void **) &rk,
(void **) &adb, &cursor))
{
&cursor);
!rc;
rc = skiplist_next(rfd->advertised.ip0_by_ether,
(void **)&rk, (void **)&adb,
&cursor)) {
uint32_t lt = adb->lifetime;
@ -466,15 +432,9 @@ rfapiApAdjustLifetimeStats (
* 0 No need to advertise tunnel route
* non-0 advertise tunnel route
*/
int
rfapiApAdd (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
struct prefix_rd *prd,
uint32_t lifetime,
uint8_t cost,
int rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *pfx_ip, struct prefix *pfx_eth,
struct prefix_rd *prd, uint32_t lifetime, uint8_t cost,
struct rfapi_l2address_option *l2o) /* other options TBD */
{
int rc;
@ -484,55 +444,45 @@ rfapiApAdd (
struct rfapi_rib_key rk;
rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk);
if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
{
if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) {
use_ip0 = 1;
assert(pfx_eth);
rc =
skiplist_search (rfd->advertised.ip0_by_ether, &rk,
rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk,
(void **)&adb);
}
else
{
} else {
/* find prefix in advertised prefixes list */
rc =
skiplist_search (rfd->advertised.ipN_by_prefix, &rk,
rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk,
(void **)&adb);
}
if (rc)
{
if (rc) {
/* Not found */
adb = XCALLOC(MTYPE_RFAPI_ADB, sizeof(struct rfapi_adb));
assert(adb);
adb->lifetime = lifetime;
adb->u.key = rk;
if (use_ip0)
{
if (use_ip0) {
assert(pfx_eth);
skiplist_insert (rfd->advertised.ip0_by_ether, &adb->u.key,
adb);
}
else
{
skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->u.key,
adb);
skiplist_insert(rfd->advertised.ip0_by_ether,
&adb->u.key, adb);
} else {
skiplist_insert(rfd->advertised.ipN_by_prefix,
&adb->u.key, adb);
}
skiplist_insert(rfd->advertised.by_lifetime, adb, adb);
}
else
{
} else {
old_lifetime = adb->lifetime;
if (old_lifetime != lifetime)
{
assert (!skiplist_delete (rfd->advertised.by_lifetime, adb, NULL));
if (old_lifetime != lifetime) {
assert(!skiplist_delete(rfd->advertised.by_lifetime,
adb, NULL));
adb->lifetime = lifetime;
assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb));
assert(!skiplist_insert(rfd->advertised.by_lifetime,
adb, adb));
}
}
adb->cost = cost;
@ -541,8 +491,8 @@ rfapiApAdd (
else
memset(&adb->l2o, 0, sizeof(struct rfapi_l2address_option));
if (rfapiApAdjustLifetimeStats
(rfd, (rc ? NULL : &old_lifetime), &lifetime))
if (rfapiApAdjustLifetimeStats(rfd, (rc ? NULL : &old_lifetime),
&lifetime))
return 1;
return 0;
@ -552,14 +502,9 @@ rfapiApAdd (
* After this function returns successfully, caller should call
* rfapiAdjustLifetimeStats() and possibly rfapiTunnelRouteAnnounce()
*/
int
rfapiApDelete (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
struct prefix_rd *prd,
int *advertise_tunnel) /* out */
int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *pfx_ip, struct prefix *pfx_eth,
struct prefix_rd *prd, int *advertise_tunnel) /* out */
{
int rc;
struct rfapi_adb *adb;
@ -572,38 +517,29 @@ rfapiApDelete (
rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk);
/* find prefix in advertised prefixes list */
if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
{
if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) {
use_ip0 = 1;
assert(pfx_eth);
rc =
skiplist_search (rfd->advertised.ip0_by_ether, &rk,
rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk,
(void **)&adb);
}
else
{
} else {
/* find prefix in advertised prefixes list */
rc =
skiplist_search (rfd->advertised.ipN_by_prefix, &rk,
rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk,
(void **)&adb);
}
if (rc)
{
if (rc) {
return ENOENT;
}
old_lifetime = adb->lifetime;
if (use_ip0)
{
if (use_ip0) {
rc = skiplist_delete(rfd->advertised.ip0_by_ether, &rk, NULL);
}
else
{
} else {
rc = skiplist_delete(rfd->advertised.ipN_by_prefix, &rk, NULL);
}
assert(!rc);
@ -613,8 +549,7 @@ rfapiApDelete (
rfapiAdbFree(adb);
if (rfapiApAdjustLifetimeStats (rfd, &old_lifetime, NULL))
{
if (rfapiApAdjustLifetimeStats(rfd, &old_lifetime, NULL)) {
if (advertise_tunnel)
*advertise_tunnel = 1;
}

View File

@ -56,42 +56,28 @@
#include "rfapi_rib.h"
extern void
rfapiApInit (struct rfapi_advertised_prefixes *ap);
extern void rfapiApInit(struct rfapi_advertised_prefixes *ap);
extern void
rfapiApRelease (struct rfapi_advertised_prefixes *ap);
extern void rfapiApRelease(struct rfapi_advertised_prefixes *ap);
extern int rfapiApCount(struct rfapi_descriptor *rfd);
extern int rfapiApCountAll(struct bgp *bgp);
extern void rfapiApReadvertiseAll(struct bgp *bgp,
struct rfapi_descriptor *rfd);
extern void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd);
extern int
rfapiApCount (struct rfapi_descriptor *rfd);
extern int
rfapiApCountAll (struct bgp *bgp);
extern void
rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd);
extern void
rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd);
extern int
rfapiApAdd (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
struct prefix_rd *prd,
uint32_t lifetime,
rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *pfx_ip,
struct prefix *pfx_eth, struct prefix_rd *prd, uint32_t lifetime,
uint8_t cost,
struct rfapi_l2address_option *l2o); /* other options TBD */
extern int
rfapiApDelete (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *pfx_ip,
struct prefix *pfx_eth,
extern int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *pfx_ip, struct prefix *pfx_eth,
struct prefix_rd *prd,
int *advertise_tunnel); /* out */

View File

@ -35,38 +35,26 @@ extern void rfapi_delete (struct bgp *);
struct rfapi *bgp_rfapi_new(struct bgp *bgp);
void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h);
extern void
rfapiProcessUpdate (struct peer *peer,
void *rfd,
struct prefix *p,
struct prefix_rd *prd,
struct attr *attr,
afi_t afi,
safi_t safi,
u_char type, u_char sub_type, uint32_t * label);
extern void rfapiProcessUpdate(struct peer *peer, void *rfd, struct prefix *p,
struct prefix_rd *prd, struct attr *attr,
afi_t afi, safi_t safi, u_char type,
u_char sub_type, uint32_t *label);
extern void
rfapiProcessWithdraw (struct peer *peer,
void *rfd,
struct prefix *p,
struct prefix_rd *prd,
struct attr *attr,
extern void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p,
struct prefix_rd *prd, struct attr *attr,
afi_t afi, safi_t safi, u_char type, int kill);
extern void rfapiProcessPeerDown(struct peer *peer);
extern void
vnc_zebra_announce (struct prefix *p,
struct bgp_info *new_select, struct bgp *bgp);
extern void vnc_zebra_announce(struct prefix *p, struct bgp_info *new_select,
struct bgp *bgp);
extern void
vnc_zebra_withdraw (struct prefix *p, struct bgp_info *old_select);
extern void vnc_zebra_withdraw(struct prefix *p, struct bgp_info *old_select);
extern void
rfapi_vty_out_vncinfo (struct vty *vty,
struct prefix *p, struct bgp_info *bi, safi_t safi);
extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p,
struct bgp_info *bi, safi_t safi);
extern void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi);

View File

@ -36,8 +36,7 @@
#include "bgpd/rfapi/vnc_debug.h"
void *
rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)
void *rfapi_create_generic(struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)
{
struct rfapi_descriptor *rfd;
rfd = XCALLOC(MTYPE_RFAPI_DESC, sizeof(struct rfapi_descriptor));
@ -60,8 +59,7 @@ rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)
* return value:
*
*------------------------------------------*/
void
rfapi_free_generic (void *grfd)
void rfapi_free_generic(void *grfd)
{
struct rfapi_descriptor *rfd;
rfd = (struct rfapi_descriptor *)grfd;
@ -84,8 +82,7 @@ rfapi_free_generic (void *grfd)
* 0 Mismatch
* 1 Match
*------------------------------------------*/
int
rfapi_compare_rfds (void *rfd1, void *rfd2)
int rfapi_compare_rfds(void *rfd1, void *rfd2)
{
struct rfapi_descriptor *rrfd1, *rrfd2;
int match = 0;
@ -93,8 +90,7 @@ rfapi_compare_rfds (void *rfd1, void *rfd2)
rrfd1 = (struct rfapi_descriptor *)rfd1;
rrfd2 = (struct rfapi_descriptor *)rfd2;
if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family)
{
if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family) {
if (rrfd1->vn_addr.addr_family == AF_INET)
match = IPV4_ADDR_SAME(&(rrfd1->vn_addr.addr.v4),
&(rrfd2->vn_addr.addr.v4));
@ -114,8 +110,7 @@ rfapi_compare_rfds (void *rfd1, void *rfd2)
* do the process again for the UN addresses.
*/
match = 0;
if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family)
{
if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family) {
/* VN addresses match
* UN address families match
* now check the actual UN addresses

View File

@ -37,10 +37,8 @@
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#include "bgpd/rfapi/vnc_debug.h"
static void
rfapi_add_endpoint_address_to_subtlv (
struct bgp *bgp,
struct rfapi_ip_addr *ea,
static void rfapi_add_endpoint_address_to_subtlv(
struct bgp *bgp, struct rfapi_ip_addr *ea,
struct bgp_tea_subtlv_remote_endpoint *subtlv)
{
subtlv->family = ea->addr_family;
@ -52,37 +50,36 @@ rfapi_add_endpoint_address_to_subtlv (
}
bgp_encap_types
rfapi_tunneltype_option_to_tlv (
struct bgp *bgp,
struct rfapi_ip_addr *ea,
rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea,
struct rfapi_tunneltype_option *tto,
struct attr *attr,
int always_add)
struct attr *attr, int always_add)
{
#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype) \
if ((always_add || (bgp->rfapi_cfg && \
!CHECK_FLAG(bgp->rfapi_cfg->flags, \
BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) && \
ea && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \
if ((always_add \
|| (bgp->rfapi_cfg \
&& !CHECK_FLAG(bgp->rfapi_cfg->flags, \
BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) \
&& ea \
&& !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \
BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) { \
rfapi_add_endpoint_address_to_subtlv(bgp, ea, \
&tto->bgpinfo.ttype.st_endpoint); \
SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \
rfapi_add_endpoint_address_to_subtlv( \
bgp, ea, &tto->bgpinfo.ttype.st_endpoint); \
SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, \
BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \
}
struct rfapi_tunneltype_option dto;
if (tto == NULL)
{ /* create default type */
if (tto == NULL) { /* create default type */
tto = &dto;
memset(tto, 0, sizeof(dto));
tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT;
}
switch (tto->type)
{
switch (tto->type) {
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(l2tpv3_ip);
bgp_encap_type_l2tpv3overip_to_tlv (&tto->bgpinfo.l2tpv3_ip, attr);
bgp_encap_type_l2tpv3overip_to_tlv(&tto->bgpinfo.l2tpv3_ip,
attr);
break;
case BGP_ENCAP_TYPE_GRE:
@ -92,26 +89,26 @@ rfapi_tunneltype_option_to_tlv (
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(transmit_tunnel_endpoint);
bgp_encap_type_transmit_tunnel_endpoint (&tto->bgpinfo.transmit_tunnel_endpoint,
attr);
bgp_encap_type_transmit_tunnel_endpoint(
&tto->bgpinfo.transmit_tunnel_endpoint, attr);
break;
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ipsec_tunnel);
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv (&tto->bgpinfo.ipsec_tunnel,
attr);
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
&tto->bgpinfo.ipsec_tunnel, attr);
break;
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ipsec);
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv
(&tto->bgpinfo.ip_ipsec, attr);
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
&tto->bgpinfo.ip_ipsec, attr);
break;
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_ipsec);
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv
(&tto->bgpinfo.mpls_ipsec, attr);
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
&tto->bgpinfo.mpls_ipsec, attr);
break;
case BGP_ENCAP_TYPE_IP_IN_IP:
@ -159,34 +156,29 @@ rfapi_tunneltype_option_to_tlv (
return tto->type;
}
struct rfapi_un_option *
rfapi_encap_tlv_to_un_option (struct attr *attr)
struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr)
{
struct attr_extra *attre = attr->extra;
struct rfapi_un_option *uo = NULL;
struct rfapi_tunneltype_option *tto;
int rc;
struct bgp_attr_encap_subtlv *stlv;
if (!attre)
return NULL;
/* no tunnel encap attr stored */
if (!attre->encap_tunneltype)
if (!attr->encap_tunneltype)
return NULL;
stlv = attre->encap_subtlvs;
stlv = attr->encap_subtlvs;
uo = XCALLOC(MTYPE_RFAPI_UN_OPTION, sizeof(struct rfapi_un_option));
assert(uo);
uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE;
uo->v.tunnel.type = attre->encap_tunneltype;
uo->v.tunnel.type = attr->encap_tunneltype;
tto = &uo->v.tunnel;
switch (attre->encap_tunneltype)
{
switch (attr->encap_tunneltype) {
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
rc = tlv_to_bgp_encap_type_l2tpv3overip (stlv, &tto->bgpinfo.l2tpv3_ip);
rc = tlv_to_bgp_encap_type_l2tpv3overip(
stlv, &tto->bgpinfo.l2tpv3_ip);
break;
case BGP_ENCAP_TYPE_GRE:
@ -194,25 +186,23 @@ rfapi_encap_tlv_to_un_option (struct attr *attr)
break;
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint (stlv,
&tto->bgpinfo.transmit_tunnel_endpoint);
rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
stlv, &tto->bgpinfo.transmit_tunnel_endpoint);
break;
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode (stlv,
&tto->bgpinfo.ipsec_tunnel);
rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
stlv, &tto->bgpinfo.ipsec_tunnel);
break;
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
rc =
tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stlv,
&tto->bgpinfo.ip_ipsec);
rc = tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
stlv, &tto->bgpinfo.ip_ipsec);
break;
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
rc =
tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode
(stlv, &tto->bgpinfo.mpls_ipsec);
rc = tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
stlv, &tto->bgpinfo.mpls_ipsec);
break;
case BGP_ENCAP_TYPE_IP_IN_IP:
@ -232,15 +222,18 @@ rfapi_encap_tlv_to_un_option (struct attr *attr)
break;
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
rc = tlv_to_bgp_encap_type_mpls_in_gre (stlv, &tto->bgpinfo.mpls_gre);
rc = tlv_to_bgp_encap_type_mpls_in_gre(stlv,
&tto->bgpinfo.mpls_gre);
break;
case BGP_ENCAP_TYPE_VXLAN_GPE:
rc = tlv_to_bgp_encap_type_vxlan_gpe (stlv, &tto->bgpinfo.vxlan_gpe);
rc = tlv_to_bgp_encap_type_vxlan_gpe(stlv,
&tto->bgpinfo.vxlan_gpe);
break;
case BGP_ENCAP_TYPE_MPLS_IN_UDP:
rc = tlv_to_bgp_encap_type_mpls_in_udp (stlv, &tto->bgpinfo.mpls_udp);
rc = tlv_to_bgp_encap_type_mpls_in_udp(stlv,
&tto->bgpinfo.mpls_udp);
break;
case BGP_ENCAP_TYPE_PBB:
@ -248,13 +241,12 @@ rfapi_encap_tlv_to_un_option (struct attr *attr)
break;
default:
vnc_zlog_debug_verbose ("%s: unknown tunnel type %d",
__func__, attre->encap_tunneltype);
vnc_zlog_debug_verbose("%s: unknown tunnel type %d", __func__,
attr->encap_tunneltype);
rc = -1;
break;
}
if (rc)
{
if (rc) {
XFREE(MTYPE_RFAPI_UN_OPTION, uo);
uo = NULL;
}
@ -265,10 +257,8 @@ rfapi_encap_tlv_to_un_option (struct attr *attr)
* SUBTLV PRINT
***********************************************************************/
static void
subtlv_print_encap_l2tpv3_over_ip (
void *stream,
int column_offset,
static void subtlv_print_encap_l2tpv3_over_ip(
void *stream, int column_offset,
struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
{
int (*fp)(void *, const char *, ...);
@ -285,14 +275,11 @@ subtlv_print_encap_l2tpv3_over_ip (
vty_newline);
fp(out, "%*s SessionID: %d%s", column_offset, "", st->sessionid,
vty_newline);
fp (out, "%*s Cookie: (length %d)%s", column_offset, "", st->cookie_length,
vty_newline);
fp(out, "%*s Cookie: (length %d)%s", column_offset, "",
st->cookie_length, vty_newline);
}
static void
subtlv_print_encap_gre (
void *stream,
int column_offset,
static void subtlv_print_encap_gre(void *stream, int column_offset,
struct bgp_tea_subtlv_encap_gre_key *st)
{
int (*fp)(void *, const char *, ...);
@ -305,15 +292,13 @@ subtlv_print_encap_gre (
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", vty_newline);
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)",
vty_newline);
fp(out, "%*s GRE key: %d (0x%x)%s", column_offset, "", st->gre_key,
st->gre_key, vty_newline);
}
static void
subtlv_print_encap_pbb (
void *stream,
int column_offset,
static void subtlv_print_encap_pbb(void *stream, int column_offset,
struct bgp_tea_subtlv_encap_pbb *st)
{
int (*fp)(void *, const char *, ...);
@ -326,29 +311,22 @@ subtlv_print_encap_pbb (
if (!st)
return;
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", vty_newline);
if (st->flag_isid)
{
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)",
vty_newline);
if (st->flag_isid) {
fp(out, "%*s ISID: %d (0x%x)%s", column_offset, "", st->isid,
st->isid, vty_newline);
}
if (st->flag_vid)
{
fp (out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid, st->vid,
vty_newline);
if (st->flag_vid) {
fp(out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid,
st->vid, vty_newline);
}
fp (out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s",
column_offset, "",
st->macaddr[0],
st->macaddr[1],
st->macaddr[2],
st->macaddr[3], st->macaddr[4], st->macaddr[5], vty_newline);
fp(out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", column_offset,
"", st->macaddr[0], st->macaddr[1], st->macaddr[2], st->macaddr[3],
st->macaddr[4], st->macaddr[5], vty_newline);
}
static void
subtlv_print_proto_type (
void *stream,
int column_offset,
static void subtlv_print_proto_type(void *stream, int column_offset,
struct bgp_tea_subtlv_proto_type *st)
{
int (*fp)(void *, const char *, ...);
@ -363,14 +341,11 @@ subtlv_print_proto_type (
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)",
vty_newline);
fp (out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto, st->proto,
vty_newline);
fp(out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto,
st->proto, vty_newline);
}
static void
subtlv_print_color (
void *stream,
int column_offset,
static void subtlv_print_color(void *stream, int column_offset,
struct bgp_tea_subtlv_color *st)
{
int (*fp)(void *, const char *, ...);
@ -384,14 +359,11 @@ subtlv_print_color (
return;
fp(out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline);
fp (out, "%*s Color: %d (0x%x)", column_offset, "", st->color, st->color,
vty_newline);
fp(out, "%*s Color: %d (0x%x)", column_offset, "", st->color,
st->color, vty_newline);
}
static void
subtlv_print_ipsec_ta (
void *stream,
int column_offset,
static void subtlv_print_ipsec_ta(void *stream, int column_offset,
struct bgp_tea_subtlv_ipsec_ta *st)
{
int (*fp)(void *, const char *, ...);
@ -416,9 +388,7 @@ subtlv_print_ipsec_ta (
***********************************************************************/
static void
print_encap_type_l2tpv3overip (
void *stream,
int column_offset,
print_encap_type_l2tpv3overip(void *stream, int column_offset,
struct bgp_encap_type_l2tpv3_over_ip *bet)
{
const char *type = "L2TPv3 over IP";
@ -440,10 +410,7 @@ print_encap_type_l2tpv3overip (
subtlv_print_color(stream, column_offset + 2, &bet->st_color);
}
static void
print_encap_type_gre (
void *stream,
int column_offset,
static void print_encap_type_gre(void *stream, int column_offset,
struct bgp_encap_type_gre *bet)
{
const char *type = "GRE";
@ -464,10 +431,7 @@ print_encap_type_gre (
subtlv_print_color(stream, column_offset + 2, &bet->st_color);
}
static void
print_encap_type_ip_in_ip (
void *stream,
int column_offset,
static void print_encap_type_ip_in_ip(void *stream, int column_offset,
struct bgp_encap_type_ip_in_ip *bet)
{
const char *type = "IP in IP";
@ -487,10 +451,8 @@ print_encap_type_ip_in_ip (
subtlv_print_color(stream, column_offset + 2, &bet->st_color);
}
static void
print_encap_type_transmit_tunnel_endpoint (
void *stream,
int column_offset,
static void print_encap_type_transmit_tunnel_endpoint(
void *stream, int column_offset,
struct bgp_encap_type_transmit_tunnel_endpoint *bet)
{
const char *type = "Transmit Tunnel Endpoint";
@ -509,10 +471,8 @@ print_encap_type_transmit_tunnel_endpoint (
/* no subtlvs for this type */
}
static void
print_encap_type_ipsec_in_tunnel_mode (
void *stream,
int column_offset,
static void print_encap_type_ipsec_in_tunnel_mode(
void *stream, int column_offset,
struct bgp_encap_type_ipsec_in_tunnel_mode *bet)
{
const char *type = "IPSEC in Tunnel mode";
@ -530,10 +490,8 @@ print_encap_type_ipsec_in_tunnel_mode (
subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
}
static void
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (
void *stream,
int column_offset,
static void print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
void *stream, int column_offset,
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
{
const char *type = "IP in IP Tunnel with IPSEC transport mode";
@ -552,10 +510,8 @@ print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (
subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
}
static void
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (
void *stream,
int column_offset,
static void print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
void *stream, int column_offset,
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
{
const char *type = "MPLS in IP Tunnel with IPSEC transport mode";
@ -575,10 +531,7 @@ print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (
}
static void
print_encap_type_pbb (
void *stream,
int column_offset,
static void print_encap_type_pbb(void *stream, int column_offset,
struct bgp_encap_type_pbb *bet)
{
const char *type = "PBB";
@ -598,10 +551,7 @@ print_encap_type_pbb (
}
static void
print_encap_type_vxlan (
void *stream,
int column_offset,
static void print_encap_type_vxlan(void *stream, int column_offset,
struct bgp_encap_type_vxlan *bet)
{
const char *type = "VXLAN";
@ -621,10 +571,7 @@ print_encap_type_vxlan (
}
static void
print_encap_type_nvgre (
void *stream,
int column_offset,
static void print_encap_type_nvgre(void *stream, int column_offset,
struct bgp_encap_type_nvgre *bet)
{
const char *type = "NVGRE";
@ -643,10 +590,7 @@ print_encap_type_nvgre (
/* no subtlvs for this type */
}
static void
print_encap_type_mpls (
void *stream,
int column_offset,
static void print_encap_type_mpls(void *stream, int column_offset,
struct bgp_encap_type_mpls *bet)
{
const char *type = "MPLS";
@ -665,10 +609,7 @@ print_encap_type_mpls (
/* no subtlvs for this type */
}
static void
print_encap_type_mpls_in_gre (
void *stream,
int column_offset,
static void print_encap_type_mpls_in_gre(void *stream, int column_offset,
struct bgp_encap_type_mpls_in_gre *bet)
{
const char *type = "MPLS in GRE";
@ -687,10 +628,7 @@ print_encap_type_mpls_in_gre (
/* no subtlvs for this type */
}
static void
print_encap_type_vxlan_gpe (
void *stream,
int column_offset,
static void print_encap_type_vxlan_gpe(void *stream, int column_offset,
struct bgp_encap_type_vxlan_gpe *bet)
{
const char *type = "VXLAN GPE";
@ -709,10 +647,7 @@ print_encap_type_vxlan_gpe (
/* no subtlvs for this type */
}
static void
print_encap_type_mpls_in_udp (
void *stream,
int column_offset,
static void print_encap_type_mpls_in_udp(void *stream, int column_offset,
struct bgp_encap_type_mpls_in_udp *bet)
{
const char *type = "MPLS in UDP";
@ -731,14 +666,10 @@ print_encap_type_mpls_in_udp (
/* no subtlvs for this type */
}
void
rfapi_print_tunneltype_option (
void *stream,
int column_offset,
void rfapi_print_tunneltype_option(void *stream, int column_offset,
struct rfapi_tunneltype_option *tto)
{
switch (tto->type)
{
switch (tto->type) {
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
print_encap_type_l2tpv3overip(stream, column_offset,
&tto->bgpinfo.l2tpv3_ip);
@ -749,41 +680,44 @@ rfapi_print_tunneltype_option (
break;
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
print_encap_type_transmit_tunnel_endpoint (stream, column_offset,
print_encap_type_transmit_tunnel_endpoint(
stream, column_offset,
&tto->bgpinfo.transmit_tunnel_endpoint);
break;
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
print_encap_type_ipsec_in_tunnel_mode (stream, column_offset,
&tto->bgpinfo.ipsec_tunnel);
print_encap_type_ipsec_in_tunnel_mode(
stream, column_offset, &tto->bgpinfo.ipsec_tunnel);
break;
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stream,
column_offset,
&tto->bgpinfo.ip_ipsec);
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
stream, column_offset, &tto->bgpinfo.ip_ipsec);
break;
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (stream,
column_offset,
&tto->bgpinfo.mpls_ipsec);
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
stream, column_offset, &tto->bgpinfo.mpls_ipsec);
break;
case BGP_ENCAP_TYPE_IP_IN_IP:
print_encap_type_ip_in_ip (stream, column_offset, &tto->bgpinfo.ip_ip);
print_encap_type_ip_in_ip(stream, column_offset,
&tto->bgpinfo.ip_ip);
break;
case BGP_ENCAP_TYPE_VXLAN:
print_encap_type_vxlan (stream, column_offset, &tto->bgpinfo.vxlan);
print_encap_type_vxlan(stream, column_offset,
&tto->bgpinfo.vxlan);
break;
case BGP_ENCAP_TYPE_NVGRE:
print_encap_type_nvgre (stream, column_offset, &tto->bgpinfo.nvgre);
print_encap_type_nvgre(stream, column_offset,
&tto->bgpinfo.nvgre);
break;
case BGP_ENCAP_TYPE_MPLS:
print_encap_type_mpls (stream, column_offset, &tto->bgpinfo.mpls);
print_encap_type_mpls(stream, column_offset,
&tto->bgpinfo.mpls);
break;
case BGP_ENCAP_TYPE_MPLS_IN_GRE:

View File

@ -22,20 +22,13 @@
#define RFAPI_BGP_ENCAP_TYPE_DEFAULT BGP_ENCAP_TYPE_IP_IN_IP
extern bgp_encap_types
rfapi_tunneltype_option_to_tlv (
struct bgp *bgp,
struct rfapi_ip_addr *ea,
rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea,
struct rfapi_tunneltype_option *tto,
struct attr *attr,
int always_add);
struct attr *attr, int always_add);
extern struct rfapi_un_option *
rfapi_encap_tlv_to_un_option (struct attr *attr);
extern struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr);
extern void
rfapi_print_tunneltype_option (
void *stream,
int column_offset,
extern void rfapi_print_tunneltype_option(void *stream, int column_offset,
struct rfapi_tunneltype_option *tto);

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,7 @@
* routes are not segregated by RD - the RD is stored in bgp_info_extra
* and is needed to determine if two prefixes are the same.
*/
struct rfapi_import_table
{
struct rfapi_import_table {
struct rfapi_import_table *next;
struct rfapi_nve_group_cfg *rfg;
struct ecommunity *rt_import_list; /* copied from nve grp */
@ -56,7 +55,8 @@ struct rfapi_import_table
(((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP))
#define RFAPI_DIRECT_IMPORT_BI(bi) \
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) || ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) \
|| ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \
if (RFAPI_LOCAL_BI(bi)) { \
@ -68,37 +68,25 @@ struct rfapi_import_table
(itable)->remote_count[(afi)] += (cnt); \
}
extern uint8_t
rfapiRfpCost (struct attr *attr);
extern uint8_t rfapiRfpCost(struct attr *attr);
extern void
rfapiDebugBacktrace (void);
extern void rfapiDebugBacktrace(void);
extern void
rfapiCheckRouteCount (void);
extern void rfapiCheckRouteCount(void);
/*
* Print BI in an Import Table
*/
extern void
rfapiPrintBi (void *stream, struct bgp_info *bi);
extern void rfapiPrintBi(void *stream, struct bgp_info *bi);
extern void
rfapiShowImportTable (
void *stream,
const char *label,
struct route_table *rt,
int isvpn);
extern void rfapiShowImportTable(void *stream, const char *label,
struct route_table *rt, int isvpn);
extern struct rfapi_import_table *
rfapiImportTableRefAdd (
struct bgp *bgp,
struct ecommunity *rt_import_list,
rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list,
struct rfapi_nve_group_cfg *rfg);
extern void
rfapiImportTableRefDelByIt (
struct bgp *bgp,
extern void rfapiImportTableRefDelByIt(struct bgp *bgp,
struct rfapi_import_table *it_target);
@ -111,53 +99,41 @@ rfapiImportTableRefDelByIt (
* then return those, and also include all the non-removed routes from the
* next less-specific node (i.e., this node's parent) at the end.
*/
extern struct rfapi_next_hop_entry *
rfapiRouteNode2NextHopList (
struct route_node *rn,
uint32_t lifetime, /* put into nexthop entries */
extern struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rfd_rib_table, /* preload this NVE rib table */
struct prefix *pfx_target_original); /* query target */
extern struct rfapi_next_hop_entry *
rfapiRouteTable2NextHopList (
extern struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList(
struct route_table *rt,
uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rfd_rib_table, /* preload this NVE rib table */
struct prefix *pfx_target_original); /* query target */
extern struct rfapi_next_hop_entry *
rfapiEthRouteTable2NextHopList (
uint32_t logical_net_id,
struct rfapi_ip_prefix *rprefix,
extern struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList(
uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix,
uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rib_route_table, /* preload NVE rib node */
struct prefix *pfx_target_original); /* query target */
extern int
rfapiEcommunitiesIntersect (struct ecommunity *e1, struct ecommunity *e2);
extern int rfapiEcommunitiesIntersect(struct ecommunity *e1,
struct ecommunity *e2);
extern void
rfapiCheckRefcount (struct route_node *rn, safi_t safi, int lockoffset);
extern void rfapiCheckRefcount(struct route_node *rn, safi_t safi,
int lockoffset);
extern int
rfapiHasNonRemovedRoutes (struct route_node *rn);
extern int rfapiHasNonRemovedRoutes(struct route_node *rn);
extern int
rfapiProcessDeferredClose (struct thread *t);
extern int rfapiProcessDeferredClose(struct thread *t);
extern int
rfapiGetUnAddrOfVpnBi (struct bgp_info *bi, struct prefix *p);
extern int rfapiGetUnAddrOfVpnBi(struct bgp_info *bi, struct prefix *p);
extern void
rfapiNexthop2Prefix (struct attr *attr, struct prefix *p);
extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p);
extern void
rfapiUnicastNexthop2Prefix (
afi_t afi,
struct attr *attr,
extern void rfapiUnicastNexthop2Prefix(afi_t afi, struct attr *attr,
struct prefix *p);
/* Filtered Import Function actions */
@ -165,51 +141,35 @@ rfapiUnicastNexthop2Prefix (
#define FIF_ACTION_WITHDRAW 1
#define FIF_ACTION_KILL 2
extern void
rfapiBgpInfoFilteredImportVPN (
struct rfapi_import_table *import_table,
int action,
struct peer *peer,
extern void rfapiBgpInfoFilteredImportVPN(
struct rfapi_import_table *import_table, int action, struct peer *peer,
void *rfd, /* set for looped back routes */
struct prefix *p,
struct prefix *aux_prefix, /* AFI_ETHER: optional IP */
afi_t afi,
struct prefix_rd *prd,
afi_t afi, struct prefix_rd *prd,
struct attr *attr, /* part of bgp_info */
u_char type, /* part of bgp_info */
u_char sub_type, /* part of bgp_info */
uint32_t *label); /* part of bgp_info */
extern struct rfapi_next_hop_entry *
rfapiEthRouteNode2NextHopList (
struct route_node *rn,
struct rfapi_ip_prefix *rprefix,
extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
struct route_node *rn, struct rfapi_ip_prefix *rprefix,
uint32_t lifetime, /* put into nexthop entries */
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
struct route_table *rib_route_table, /* preload NVE rib table */
struct prefix *pfx_target_original); /* query target */
extern struct rfapi_import_table *
rfapiMacImportTableGetNoAlloc (
struct bgp *bgp,
extern struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp,
uint32_t lni);
extern struct rfapi_import_table *
rfapiMacImportTableGet (
struct bgp *bgp,
extern struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp,
uint32_t lni);
extern int
rfapiGetL2o (
struct attr *attr,
struct rfapi_l2address_option *l2o);
extern int rfapiGetL2o(struct attr *attr, struct rfapi_l2address_option *l2o);
extern int rfapiEcommunityGetLNI (
struct ecommunity *ecom,
uint32_t *lni);
extern int rfapiEcommunityGetLNI(struct ecommunity *ecom, uint32_t *lni);
extern int rfapiEcommunityGetEthernetTag (
struct ecommunity *ecom,
extern int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom,
uint16_t *tag_id);
/* enable for debugging; disable for performance */
@ -239,14 +199,10 @@ extern int rfapiEcommunityGetEthernetTag (
* return value:
* void
--------------------------------------------*/
extern void
rfapiDeleteRemotePrefixes (
struct prefix *un,
struct prefix *vn,
extern void rfapiDeleteRemotePrefixes(struct prefix *un, struct prefix *vn,
struct prefix *p,
struct rfapi_import_table *it,
int delete_active,
int delete_holddown,
int delete_active, int delete_holddown,
uint32_t *pARcount, /* active routes */
uint32_t *pAHcount, /* active nves */
uint32_t *pHRcount, /* holddown routes */
@ -267,9 +223,7 @@ rfapiDeleteRemotePrefixes (
* return value:
* void
--------------------------------------------*/
extern void
rfapiCountAllItRoutes (
int *pALRcount, /* active local routes */
extern void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */
int *pARRcount, /* active remote routes */
int *pHRcount, /* holddown routes */
int *pIRcount); /* direct imported routes */
@ -287,7 +241,6 @@ rfapiCountAllItRoutes (
* and RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY
*
--------------------------------------------*/
extern uint32_t
rfapiGetHolddownFromLifetime (uint32_t lifetime);
extern uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime);
#endif /* QUAGGA_HGP_RFAPI_IMPORT_H */

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,7 @@
* These get attached to the nodes in an import table (using "aggregate" ptr)
* to indicate which nves are interested in a prefix/target
*/
struct rfapi_monitor_vpn
{
struct rfapi_monitor_vpn {
struct rfapi_monitor_vpn *next; /* chain from struct route_node */
struct rfapi_descriptor *rfd; /* which NVE requested the route */
struct prefix p; /* constant: pfx in original request */
@ -42,8 +41,7 @@ struct rfapi_monitor_vpn
struct thread *timer;
};
struct rfapi_monitor_encap
{
struct rfapi_monitor_encap {
struct rfapi_monitor_encap *next;
struct rfapi_monitor_encap *prev;
struct route_node *node; /* VPN node */
@ -51,8 +49,7 @@ struct rfapi_monitor_encap
struct route_node *rn; /* parent node */
};
struct rfapi_monitor_eth
{
struct rfapi_monitor_eth {
struct rfapi_monitor_eth *next; /* for use in vpn0_queries list */
struct rfapi_descriptor *rfd; /* which NVE requested the route */
struct ethaddr macaddr;
@ -75,35 +72,36 @@ struct rfapi_monitor_eth
* - one lock per chained struct rfapi_monitor_encap
*
*/
struct rfapi_it_extra
{
union
{
struct
{
struct rfapi_it_extra {
union {
struct {
struct rfapi_monitor_vpn *v;
struct skiplist *idx_rd; /* RD index */
struct skiplist *mon_eth; /* ether queries */
struct
{
/* routes with UN addrs, either cached encap or Encap TLV */
struct {
/* routes with UN addrs, either cached encap or
* Encap TLV */
int valid_interior_count;
/* unicast exterior routes, key=bi, val=allocated prefix */
/* unicast exterior routes, key=bi,
* val=allocated prefix */
struct skiplist *source;
} e;
} vpn;
struct
{
struct {
struct rfapi_monitor_encap *e;
} encap;
} u;
};
#define RFAPI_IT_EXTRA_GET(rn) ((struct rfapi_it_extra *)( \
(rn)->aggregate? (rn)->aggregate: \
(route_lock_node(rn), (rn)->aggregate = \
XCALLOC(MTYPE_RFAPI_IT_EXTRA,sizeof(struct rfapi_it_extra)))))
#define RFAPI_IT_EXTRA_GET(rn) \
((struct rfapi_it_extra \
*)((rn)->aggregate \
? (rn)->aggregate \
: (route_lock_node(rn), \
(rn)->aggregate = XCALLOC( \
MTYPE_RFAPI_IT_EXTRA, \
sizeof(struct rfapi_it_extra)))))
#define RFAPI_RDINDEX(rn) \
((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd : NULL)
@ -127,89 +125,65 @@ struct rfapi_it_extra
#define RFAPI_MONITOR_EXTERIOR(rn) (&(RFAPI_IT_EXTRA_GET(rn)->u.vpn.e))
#define RFAPI_HAS_MONITOR_EXTERIOR(rn) (rn && rn->aggregate && \
((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source && \
!skiplist_first(((struct rfapi_it_extra *)(rn->aggregate))-> \
u.vpn.e.source, NULL, NULL))
#define RFAPI_HAS_MONITOR_EXTERIOR(rn) \
(rn && rn->aggregate \
&& ((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source \
&& !skiplist_first(((struct rfapi_it_extra *)(rn->aggregate)) \
->u.vpn.e.source, \
NULL, NULL))
extern void
rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain);
extern void rfapiMonitorLoopCheck(struct rfapi_monitor_vpn *mchain);
extern void
rfapiMonitorCleanCheck (struct bgp *bgp);
extern void rfapiMonitorCleanCheck(struct bgp *bgp);
extern void
rfapiMonitorCheckAttachAllowed (void);
extern void rfapiMonitorCheckAttachAllowed(void);
extern void
rfapiMonitorExtraFlush (safi_t safi, struct route_node *rn);
extern void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn);
extern struct route_node *
rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, struct prefix *p);
extern void
rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd);
extern void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd);
extern struct route_node *
rfapiMonitorAdd (
struct bgp *bgp,
extern struct route_node *rfapiMonitorAdd(struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct prefix *p);
extern void
rfapiMonitorDetachImportHd (struct rfapi_descriptor *rfd);
extern void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd);
extern void
rfapiMonitorDel (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
extern void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct prefix *p);
extern int
rfapiMonitorDelHd (struct rfapi_descriptor *rfd);
extern int rfapiMonitorDelHd(struct rfapi_descriptor *rfd);
extern void
rfapiMonitorCallbacksOff (struct bgp *bgp);
extern void rfapiMonitorCallbacksOff(struct bgp *bgp);
extern void
rfapiMonitorCallbacksOn (struct bgp *bgp);
extern void rfapiMonitorCallbacksOn(struct bgp *bgp);
extern void
rfapiMonitorResponseRemovalOff (struct bgp *bgp);
extern void rfapiMonitorResponseRemovalOff(struct bgp *bgp);
extern void
rfapiMonitorResponseRemovalOn (struct bgp *bgp);
extern void rfapiMonitorResponseRemovalOn(struct bgp *bgp);
extern void
rfapiMonitorExtraPrune (safi_t safi, struct route_node *rn);
extern void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn);
extern void
rfapiMonitorTimersRestart (struct rfapi_descriptor *rfd, struct prefix *p);
extern void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd,
struct prefix *p);
extern void
rfapiMonitorItNodeChanged (
struct rfapi_import_table *import_table,
extern void rfapiMonitorItNodeChanged(struct rfapi_import_table *import_table,
struct route_node *it_node,
struct rfapi_monitor_vpn *monitor_list);
extern void
rfapiMonitorMovedUp (
struct rfapi_import_table *import_table,
extern void rfapiMonitorMovedUp(struct rfapi_import_table *import_table,
struct route_node *old_node,
struct route_node *new_node,
struct rfapi_monitor_vpn *monitor_list);
extern struct route_node *
rfapiMonitorEthAdd (
struct bgp *bgp,
extern struct route_node *rfapiMonitorEthAdd(struct bgp *bgp,
struct rfapi_descriptor *rfd,
struct ethaddr *macaddr,
uint32_t logical_net_id);
extern void
rfapiMonitorEthDel (
struct bgp *bgp,
struct rfapi_descriptor *rfd,
extern void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
struct ethaddr *macaddr,
uint32_t logical_net_id);

Some files were not shown because too many files have changed in this diff Show More