summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_fsm.c29
-rw-r--r--bgpd/bgp_packet.c2
-rw-r--r--bgpd/bgp_route.c5
-rw-r--r--configure.ac4
-rw-r--r--doc/manpages/frr-zebra.rst5
-rw-r--r--doc/user/zebra.rst6
-rw-r--r--lib/link_state.c12
-rw-r--r--ospf6d/ospf6_flood.c1
-rw-r--r--pbrd/pbr_vty.c30
-rw-r--r--tests/topotests/pbr_topo1/test_pbr_topo1.py6
-rw-r--r--zebra/kernel_socket.c4
-rw-r--r--zebra/main.c9
-rw-r--r--zebra/redistribute.c2
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/rt_netlink.c4
-rw-r--r--zebra/zebra_rib.c2
-rw-r--r--zebra/zebra_vrf.c2
17 files changed, 80 insertions, 45 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 63e9fa7bca..92038a73e4 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -2614,12 +2614,11 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event)
{
enum bgp_fsm_status next;
enum bgp_fsm_state_progress ret = 0;
+ int fsm_result = FSM_PEER_NOOP;
struct peer *other;
int passive_conn = 0;
int dyn_nbr;
-
- /* default return code */
- ret = FSM_PEER_NOOP;
+ struct peer_connection *connection = peer->connection;
other = peer->doppelganger;
passive_conn =
@@ -2645,13 +2644,15 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event)
ret = (*(FSM[peer->connection->status - 1][event - 1].func))(
peer->connection);
- if (ret >= BGP_FSM_SUCCESS) {
+ switch (ret) {
+ case BGP_FSM_SUCCESS:
+ case BGP_FSM_SUCCESS_STATE_TRANSFER:
if (ret == BGP_FSM_SUCCESS_STATE_TRANSFER &&
next == Established) {
/* The case when doppelganger swap accurred in
bgp_establish.
Update the peer pointer accordingly */
- ret = FSM_PEER_TRANSFERRED;
+ fsm_result = FSM_PEER_TRANSFERRED;
peer = other;
}
@@ -2666,16 +2667,14 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event)
* Opting for TRANSFERRED since transfer implies
* session establishment.
*/
- if (ret != FSM_PEER_TRANSFERRED)
- ret = FSM_PEER_TRANSITIONED;
+ if (fsm_result != FSM_PEER_TRANSFERRED)
+ fsm_result = FSM_PEER_TRANSITIONED;
}
/* Make sure timer is set. */
bgp_timer_set(peer);
-
- } else {
- struct peer_connection *connection = peer->connection;
-
+ break;
+ case BGP_FSM_FAILURE:
/*
* If we got a return value of -1, that means there was an
* error, restart the FSM. Since bgp_stop() was called on the
@@ -2698,10 +2697,14 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event)
bgp_fsm_change_status(peer, Idle);
bgp_timer_set(peer);
}
- ret = FSM_PEER_STOPPED;
+ fsm_result = FSM_PEER_STOPPED;
+ break;
+ case BGP_FSM_FAILURE_AND_DELETE:
+ fsm_result = FSM_PEER_STOPPED;
+ break;
}
- return ret;
+ return fsm_result;
}
/* BGP GR Code */
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index bf7f215905..a9e772e243 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -2049,7 +2049,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
/* Network Layer Reachability Information. */
update_len = end - stream_pnt(s);
- if (update_len) {
+ if (update_len && attribute_len) {
/* Set NLRI portion to structure. */
nlris[NLRI_UPDATE].afi = AFI_IP;
nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a91292d971..dce8859bc8 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -9672,9 +9672,8 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p,
}
}
- label = decode_label(&path->extra->label[0]);
-
- if (bgp_is_valid_label(&label)) {
+ if (bgp_is_valid_label(&path->extra->label[0])) {
+ label = decode_label(&path->extra->label[0]);
if (json) {
json_object_int_add(json_out, "notag", label);
json_object_array_add(json, json_out);
diff --git a/configure.ac b/configure.ac
index 6d0ffc7adf..cea7571fe0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1385,7 +1385,9 @@ if test "$enable_protobuf3" = "yes"; then
[PROTO3=false && AC_MSG_FAILURE([protobuf3 requested but protobuf-c.h not found. Install protobuf-c.])])
fi
-AC_DEFINE([HAVE_PROTOBUF], [1], [protobuf])
+if test "$enable_protobuf" != "no"; then
+ AC_DEFINE([HAVE_PROTOBUF], [1], [protobuf])
+fi
#
# End of logic for protobuf support.
#
diff --git a/doc/manpages/frr-zebra.rst b/doc/manpages/frr-zebra.rst
index 722b011ecd..6cc46b806d 100644
--- a/doc/manpages/frr-zebra.rst
+++ b/doc/manpages/frr-zebra.rst
@@ -45,6 +45,11 @@ ROUTES
When the program terminates, do not flush routes installed by zebra from the kernel.
+.. option:: -R, --routing-table <tableno>
+
+ Specify which kernel routing table *Zebra* should communicate with.
+ If this option is not specified the default table (RT_TABLE_MAIN) is used.
+
FILES
=====
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index 39add2235f..e3c9998354 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -68,6 +68,12 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
option and we will use Route Replace Semantics instead of delete
than add.
+.. option:: --routing-table <tableno>
+
+ Specify which kernel routing table *Zebra* should communicate with.
+ If this option is not specified the default table (RT_TABLE_MAIN) is
+ used.
+
.. option:: --asic-offload=[notify_on_offload|notify_on_ack]
The linux kernel has the ability to use asic-offload ( see switchdev
diff --git a/lib/link_state.c b/lib/link_state.c
index 6537f881ce..105e3e28a9 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -523,7 +523,9 @@ struct ls_vertex *ls_vertex_update(struct ls_ted *ted, struct ls_node *node)
if (!ls_node_same(old->node, node)) {
ls_node_del(old->node);
old->node = node;
- }
+ } else
+ ls_node_del(node);
+
old->status = UPDATE;
return old;
}
@@ -805,7 +807,9 @@ struct ls_edge *ls_edge_update(struct ls_ted *ted,
if (!ls_attributes_same(old->attributes, attributes)) {
ls_attributes_del(old->attributes);
old->attributes = attributes;
- }
+ } else
+ ls_attributes_del(attributes);
+
old->status = UPDATE;
return old;
}
@@ -902,7 +906,9 @@ struct ls_subnet *ls_subnet_update(struct ls_ted *ted, struct ls_prefix *pref)
if (!ls_prefix_same(old->ls_pref, pref)) {
ls_prefix_del(old->ls_pref);
old->ls_pref = pref;
- }
+ } else
+ ls_prefix_del(pref);
+
old->status = UPDATE;
return old;
}
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index fd5a4a426e..98d3bbc519 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -1045,6 +1045,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
zlog_debug(
"%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA",
__func__);
+ ospf6_lsa_delete(new);
return;
}
} else {
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index 6d31fd75ac..582ffac9b2 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -443,27 +443,28 @@ DEFPY (pbr_map_match_dscp,
unsigned long ul_dscp;
char *pend = NULL;
- uint8_t raw_dscp;
+ uint8_t shifted_dscp;
assert(dscp);
ul_dscp = strtoul(dscp, &pend, 0);
if (pend && *pend)
- raw_dscp = pbr_map_decode_dscp_enum(dscp);
- else
- raw_dscp = ul_dscp << 2;
- if (raw_dscp > PBR_DSFIELD_DSCP) {
+ ul_dscp = pbr_map_decode_dscp_enum(dscp);
+
+ if (ul_dscp > (PBR_DSFIELD_DSCP >> 2)) {
vty_out(vty, "Invalid dscp value: %s%s\n", dscp,
((pend && *pend) ? "" : " (numeric value must be in range 0-63)"));
return CMD_WARNING_CONFIG_FAILED;
}
+ shifted_dscp = (ul_dscp << 2) & PBR_DSFIELD_DSCP;
+
if (CHECK_FLAG(pbrms->filter_bm, PBR_FILTER_DSCP) &&
- (((pbrms->dsfield & PBR_DSFIELD_DSCP) >> 2) == raw_dscp)) {
+ ((pbrms->dsfield & PBR_DSFIELD_DSCP) == shifted_dscp)) {
return CMD_SUCCESS;
}
/* Set the DSCP bits of the DSField */
- pbrms->dsfield = (pbrms->dsfield & ~PBR_DSFIELD_DSCP) | (raw_dscp << 2);
+ pbrms->dsfield = (pbrms->dsfield & ~PBR_DSFIELD_DSCP) | shifted_dscp;
SET_FLAG(pbrms->filter_bm, PBR_FILTER_DSCP);
check:
@@ -870,26 +871,27 @@ DEFPY (pbr_map_action_dscp,
unsigned long ul_dscp;
char *pend = NULL;
- uint8_t raw_dscp;
+ uint8_t shifted_dscp;
assert(dscp);
ul_dscp = strtoul(dscp, &pend, 0);
if (pend && *pend)
- raw_dscp = pbr_map_decode_dscp_enum(dscp);
- else
- raw_dscp = ul_dscp << 2;
+ ul_dscp = pbr_map_decode_dscp_enum(dscp);
- if (raw_dscp > PBR_DSFIELD_DSCP) {
+ if (ul_dscp > (PBR_DSFIELD_DSCP >> 2)) {
vty_out(vty, "Invalid dscp value: %s%s\n", dscp,
((pend && *pend) ? "" : " (numeric value must be in range 0-63)"));
return CMD_WARNING_CONFIG_FAILED;
}
+
+ shifted_dscp = (ul_dscp << 2) & PBR_DSFIELD_DSCP;
+
if (CHECK_FLAG(pbrms->action_bm, PBR_ACTION_DSCP) &&
- (pbrms->action_dscp == raw_dscp)) {
+ (pbrms->action_dscp == shifted_dscp)) {
return CMD_SUCCESS;
}
SET_FLAG(pbrms->action_bm, PBR_ACTION_DSCP);
- pbrms->action_dscp = raw_dscp;
+ pbrms->action_dscp = shifted_dscp;
check:
pbr_map_check(pbrms, true);
diff --git a/tests/topotests/pbr_topo1/test_pbr_topo1.py b/tests/topotests/pbr_topo1/test_pbr_topo1.py
index 2b437170ff..a70f2cc8da 100644
--- a/tests/topotests/pbr_topo1/test_pbr_topo1.py
+++ b/tests/topotests/pbr_topo1/test_pbr_topo1.py
@@ -215,6 +215,8 @@ ftest = [
{"c": "no match dst-port 119", "tN": r"DST Port Match: 119$"},
{"c": "match dscp cs3", "tm": r"DSCP Match: 24$"},
{"c": "no match dscp cs3", "tN": r"DSCP Match: 24$"},
+ {"c": "match dscp 5", "tm": r"DSCP Match: 5$"},
+ {"c": "no match dscp 5", "tN": r"DSCP Match: 5$"},
{"c": "match ecn 2", "tm": r"ECN Match: 2$"},
{"c": "no match ecn 2", "tN": r"ECN Match: 2$"},
{"c": "match mark 337", "tm": r"MARK Match: 337$"},
@@ -229,8 +231,8 @@ ftest = [
{"c": "no set dst-port 43", "tN": r"Set DST PORT: 43$"},
{"c": "set dscp 24", "tm": r"Set DSCP: 24$"},
{"c": "no set dscp 24", "tN": r"Set DSCP: 24$"},
- {"c": "set dscp cs7", "tm": r"Set DSCP: 14$"},
- {"c": "no set dscp cs7", "tN": r"Set DSCP: 14$"},
+ {"c": "set dscp cs7", "tm": r"Set DSCP: 56$"},
+ {"c": "no set dscp cs7", "tN": r"Set DSCP: 56$"},
{"c": "set ecn 1", "tm": r"Set ECN: 1$"},
{"c": "no set ecn 1", "tN": r"Set ECN: 1$"},
]
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index fff3e6416f..d897f4a1df 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1100,11 +1100,11 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add(afi, SAFI_UNICAST, VRF_DEFAULT, proto, 0, zebra_flags,
- &p, NULL, &nh, 0, RT_TABLE_MAIN, 0, 0, distance, 0,
+ &p, NULL, &nh, 0, rt_table_main_id, 0, 0, distance, 0,
false);
else
rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, proto, 0,
- zebra_flags, &p, NULL, &nh, 0, RT_TABLE_MAIN, 0,
+ zebra_flags, &p, NULL, &nh, 0, rt_table_main_id, 0,
distance, true);
}
diff --git a/zebra/main.c b/zebra/main.c
index aeb9739c13..1e833ce7f1 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -69,6 +69,8 @@ uint32_t rcvbufsize = RCVBUFSIZE_MIN;
uint32_t rcvbufsize = 128 * 1024;
#endif
+uint32_t rt_table_main_id = RT_TABLE_MAIN;
+
#define OPTION_V6_RR_SEMANTICS 2000
#define OPTION_ASIC_OFFLOAD 2001
#define OPTION_V6_WITH_V4_NEXTHOP 2002
@@ -88,6 +90,7 @@ const struct option longopts[] = {
{ "nl-bufsize", required_argument, NULL, 's' },
{ "v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS },
#endif /* HAVE_NETLINK */
+ {"routing-table", optional_argument, NULL, 'R'},
{ 0 }
};
@@ -298,7 +301,7 @@ int main(int argc, char **argv)
frr_preinit(&zebra_di, argc, argv);
- frr_opt_add("baz:e:rK:s:"
+ frr_opt_add("baz:e:rK:s:R:"
#ifdef HAVE_NETLINK
"n"
#endif
@@ -319,6 +322,7 @@ int main(int argc, char **argv)
#else
" -s, Set kernel socket receive buffer size\n"
#endif /* HAVE_NETLINK */
+ " -R, --routing-table Set kernel routing table\n"
);
while (1) {
@@ -373,6 +377,9 @@ int main(int argc, char **argv)
"Rcvbufsize is smaller than recommended value: %d\n",
RCVBUFSIZE_MIN);
break;
+ case 'R':
+ rt_table_main_id = atoi(optarg);
+ break;
#ifdef HAVE_NETLINK
case 'n':
vrf_configure_backend(VRF_BACKEND_NETNS);
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 8c8cbfc8d1..7aa254b1cb 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -716,7 +716,7 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id,
struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf_id);
if (!is_zebra_valid_kernel_table(table_id)
- || (table_id == RT_TABLE_MAIN))
+ || (table_id == rt_table_main_id))
return -1;
if (afi >= AFI_MAX)
diff --git a/zebra/rib.h b/zebra/rib.h
index ee36cb78a9..e20084f8cf 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -629,6 +629,8 @@ extern pid_t pid;
extern bool v6_rr_semantics;
+extern uint32_t rt_table_main_id;
+
/* Name of hook calls */
#define ZEBRA_ON_RIB_PROCESS_HOOK_CALL "on_rib_process_dplane_results"
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index a51d7b849b..2318cd6374 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -2476,7 +2476,7 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
* are trying to give me. So now we have this little hack.
*/
if (mroute->family == AF_INET)
- actual_table = (zvrf->table_id == RT_TABLE_MAIN)
+ actual_table = (zvrf->table_id == rt_table_main_id)
? RT_TABLE_DEFAULT
: zvrf->table_id;
else
@@ -4759,7 +4759,7 @@ ssize_t netlink_mpls_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
req->n.nlmsg_pid = nl->snl.nl_pid;
req->r.rtm_family = AF_MPLS;
- req->r.rtm_table = RT_TABLE_MAIN;
+ req->r.rtm_table = rt_table_main_id;
req->r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
req->r.rtm_scope = RT_SCOPE_UNIVERSE;
req->r.rtm_type = RTN_UNICAST;
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 9f1fd03df5..5a32cf6bb9 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -365,7 +365,7 @@ int is_zebra_valid_kernel_table(uint32_t table_id)
int is_zebra_main_routing_table(uint32_t table_id)
{
- if (table_id == RT_TABLE_MAIN)
+ if (table_id == rt_table_main_id)
return 1;
return 0;
}
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index b246d445da..0c063830d3 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -371,7 +371,7 @@ struct zebra_vrf *zebra_vrf_alloc(struct vrf *vrf)
zebra_vxlan_init_tables(zvrf);
zebra_mpls_init_tables(zvrf);
zebra_pw_init(zvrf);
- zvrf->table_id = RT_TABLE_MAIN;
+ zvrf->table_id = rt_table_main_id;
/* by default table ID is default one */
return zvrf;
}