diff options
| -rw-r--r-- | bgpd/bgp_fsm.c | 29 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 5 | ||||
| -rw-r--r-- | configure.ac | 4 | ||||
| -rw-r--r-- | doc/manpages/frr-zebra.rst | 5 | ||||
| -rw-r--r-- | doc/user/zebra.rst | 6 | ||||
| -rw-r--r-- | lib/link_state.c | 12 | ||||
| -rw-r--r-- | ospf6d/ospf6_flood.c | 1 | ||||
| -rw-r--r-- | pbrd/pbr_vty.c | 30 | ||||
| -rw-r--r-- | tests/topotests/pbr_topo1/test_pbr_topo1.py | 6 | ||||
| -rw-r--r-- | zebra/kernel_socket.c | 4 | ||||
| -rw-r--r-- | zebra/main.c | 9 | ||||
| -rw-r--r-- | zebra/redistribute.c | 2 | ||||
| -rw-r--r-- | zebra/rib.h | 2 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 4 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_vrf.c | 2 |
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; } |
