summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--bgpd/bgp_attr.c17
-rw-r--r--bgpd/bgp_attr.h1
-rw-r--r--bgpd/bgp_network.c6
-rw-r--r--bgpd/bgp_packet.c7
-rw-r--r--bgpd/bgp_route.c19
-rw-r--r--bgpd/bgp_routemap.c49
-rw-r--r--bgpd/bgp_vty.c1
-rw-r--r--bgpd/bgp_zebra.c10
-rw-r--r--doc/routemap.texi20
-rw-r--r--eigrpd/eigrp_const.h39
-rw-r--r--eigrpd/eigrp_fsm.c104
-rw-r--r--eigrpd/eigrp_packet.c15
-rw-r--r--eigrpd/eigrp_query.c19
-rw-r--r--eigrpd/eigrp_reply.c91
-rw-r--r--eigrpd/eigrp_structs.h1
-rw-r--r--eigrpd/eigrpd.c5
-rw-r--r--include/linux/if_bridge.h294
-rw-r--r--include/linux/if_link.h928
-rw-r--r--include/linux/lwtunnel.h70
-rw-r--r--include/linux/mpls_iptunnel.h30
-rw-r--r--include/linux/neighbour.h171
-rw-r--r--include/linux/rtnetlink.h718
-rw-r--r--include/linux/socket.h21
-rw-r--r--include/subdir.am9
-rw-r--r--lib/vrf.h1
-rw-r--r--lib/vty.c15
-rw-r--r--lib/zclient.c1
-rw-r--r--pimd/pim_cmd.c13
-rw-r--r--pimd/pim_iface.c11
-rw-r--r--pimd/pim_nht.c6
-rw-r--r--pimd/pim_zebra.c13
-rw-r--r--python/clidef.py2
-rw-r--r--zebra/if_netlink.c42
-rw-r--r--zebra/rt_netlink.c91
-rw-r--r--zebra/rt_netlink.h1
-rw-r--r--zebra/zebra_mpls.c37
-rw-r--r--zebra/zebra_mpls_netlink.c24
-rw-r--r--zebra/zebra_vty.c876
39 files changed, 2830 insertions, 952 deletions
diff --git a/Makefile.am b/Makefile.am
index b4a0e02e76..15f86dff4f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,8 @@
AUTOMAKE_OPTIONS = subdir-objects 1.12
include common.am
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \
+ -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib
AM_CFLAGS = $(WERROR)
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
LIBCAP = @LIBCAP@
@@ -34,6 +35,7 @@ $(AUTOMAKE_DUMMY)install-moduleLTLIBRARIES: install-libLTLIBRARIES
$(AUTOMAKE_DUMMY)install-binPROGRAMS: install-libLTLIBRARIES
$(AUTOMAKE_DUMMY)install-sbinPROGRAMS: install-libLTLIBRARIES
+include include/subdir.am
include lib/subdir.am
include zebra/subdir.am
include watchfrr/subdir.am
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 2d3158d847..97cfeee4e4 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1709,11 +1709,20 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
/* must have nrli_len, what is left of the attribute */
nlri_len = LEN_LEFT;
- if ((!nlri_len) || (nlri_len > STREAM_READABLE(s))) {
+ if (nlri_len > STREAM_READABLE(s)) {
zlog_info("%s: (%s) Failed to read NLRI", __func__, peer->host);
return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
}
+ if (!nlri_len) {
+ zlog_info("%s: (%s) No Reachability, Treating as a EOR marker",
+ __func__, peer->host);
+
+ mp_update->afi = afi;
+ mp_update->safi = safi;
+ return BGP_ATTR_PARSE_EOR;
+ }
+
mp_update->afi = afi;
mp_update->safi = safi;
mp_update->nlri = stream_pnt(s);
@@ -2378,6 +2387,12 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
ret = BGP_ATTR_PARSE_ERROR;
}
+ if (ret == BGP_ATTR_PARSE_EOR) {
+ if (as4_path)
+ aspath_unintern(&as4_path);
+ return ret;
+ }
+
/* If hard error occured immediately return to the caller. */
if (ret == BGP_ATTR_PARSE_ERROR) {
zlog_warn("%s: Attribute %s, parse error", peer->host,
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 6edbf43902..80ff36b59f 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -227,6 +227,7 @@ typedef enum {
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
*/
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
+ BGP_ATTR_PARSE_EOR = -4,
} bgp_attr_parse_ret_t;
struct bpacket_attr_vec_arr;
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 101e0e62bb..0d7680ea51 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -740,8 +740,10 @@ int bgp_socket(unsigned short port, const char *address)
}
freeaddrinfo(ainfo_save);
if (count == 0) {
- zlog_err("%s: no usable addresses", __func__);
- return -1;
+ zlog_err("%s: no usable addresses please check other programs usage of specified port %d",
+ __func__, port);
+ zlog_err("%s: Program cannot continue", __func__);
+ exit(-1);
}
return 0;
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 003fbaff63..a66d0590c9 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1553,7 +1553,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
* Non-MP IPv4/Unicast EoR is a completely empty UPDATE
* and MP EoR should have only an empty MP_UNREACH
*/
- if (!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) {
+ if ((!update_len && !withdraw_len &&
+ nlris[NLRI_MP_UPDATE].length == 0) ||
+ (attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
afi_t afi = 0;
safi_t safi;
@@ -1568,6 +1570,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
&& nlris[NLRI_MP_WITHDRAW].length == 0) {
afi = nlris[NLRI_MP_WITHDRAW].afi;
safi = nlris[NLRI_MP_WITHDRAW].safi;
+ } else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) {
+ afi = nlris[NLRI_MP_UPDATE].afi;
+ safi = nlris[NLRI_MP_UPDATE].safi;
}
if (afi && peer->afc[afi][safi]) {
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index af71088b7d..6230560997 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -8158,8 +8158,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
if (use_json && header) {
vty_out(vty,
- "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
- ", \"routerId\": \"%s\", \"routes\": { ",
+ "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
+ ",\n \"routerId\": \"%s\",\n \"routes\": { ",
bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id,
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
: bgp->name,
@@ -8378,7 +8378,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
p->prefixlen);
vty_out(vty, "\"%s\": ", buf2);
vty_out(vty, "%s",
- json_object_to_json_string(json_paths));
+ json_object_to_json_string_ext(json_paths, JSON_C_TO_STRING_PRETTY));
json_object_free(json_paths);
first = 0;
}
@@ -9434,8 +9434,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
"malformedAddressOrName",
ip_str);
vty_out(vty, "%s\n",
- json_object_to_json_string(
- json_no));
+ json_object_to_json_string_ext(
+ json_no, JSON_C_TO_STRING_PRETTY));
json_object_free(json_no);
} else
vty_out(vty,
@@ -9456,7 +9456,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
json_object_string_add(json_no, "warning",
"No such neighbor");
vty_out(vty, "%s\n",
- json_object_to_json_string(json_no));
+ json_object_to_json_string_ext(json_no,
+ JSON_C_TO_STRING_PRETTY));
json_object_free(json_no);
} else
vty_out(vty, "No such neighbor\n");
@@ -9865,7 +9866,8 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
json, "recommended",
"Please report this bug, with the above command output");
}
- vty_out(vty, "%s\n", json_object_to_json_string(json));
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+ JSON_C_TO_STRING_PRETTY));
json_object_free(json);
} else {
@@ -10243,7 +10245,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
output_count);
}
if (use_json) {
- vty_out(vty, "%s\n", json_object_to_json_string(json));
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+ JSON_C_TO_STRING_PRETTY));
json_object_free(json);
}
}
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 217916239c..f26498fb03 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -222,7 +222,12 @@ static void route_aspath_free(void *rule)
aspath_free(aspath);
}
-/* 'match peer (A.B.C.D|X:X::X:X)' */
+struct bgp_match_peer_compiled {
+ char *interface;
+ union sockunion su;
+};
+
+/* 'match peer (A.B.C.D|X:X::X:X|WORD)' */
/* Compares the peer specified in the 'match peer' clause with the peer
received in bgp_info->peer. If it is the same, or if the peer structure
@@ -231,6 +236,7 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix,
route_map_object_t type,
void *object)
{
+ struct bgp_match_peer_compiled *pc;
union sockunion *su;
union sockunion su_def = {
.sin = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY}};
@@ -239,12 +245,19 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix,
struct listnode *node, *nnode;
if (type == RMAP_BGP) {
- su = rule;
+ pc = rule;
+ su = &pc->su;
peer = ((struct bgp_info *)object)->peer;
- if (!CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IMPORT)
- && !CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_EXPORT))
+ if (pc->interface) {
+ if (!peer->conf_if)
+ return RMAP_NOMATCH;
+
+ if (strcmp(peer->conf_if, pc->interface) == 0)
+ return RMAP_MATCH;
+
return RMAP_NOMATCH;
+ }
/* If su='0.0.0.0' (command 'match peer local'), and it's a
NETWORK,
@@ -283,23 +296,29 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix,
static void *route_match_peer_compile(const char *arg)
{
- union sockunion *su;
+ struct bgp_match_peer_compiled *pc;
int ret;
- su = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(union sockunion));
+ pc = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+ sizeof(struct bgp_match_peer_compiled));
- ret = str2sockunion(strcmp(arg, "local") ? arg : "0.0.0.0", su);
+ ret = str2sockunion(strcmp(arg, "local") ? arg : "0.0.0.0", &pc->su);
if (ret < 0) {
- XFREE(MTYPE_ROUTE_MAP_COMPILED, su);
- return NULL;
+ pc->interface = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+ return pc;
}
- return su;
+ return pc;
}
/* Free route map's compiled `ip address' value. */
static void route_match_peer_free(void *rule)
{
+ struct bgp_match_peer_compiled *pc = rule;
+
+ if (pc->interface)
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface);
+
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
@@ -3148,11 +3167,12 @@ DEFUN (no_match_evpn_vni,
DEFUN (match_peer,
match_peer_cmd,
- "match peer <A.B.C.D|X:X::X:X>",
+ "match peer <A.B.C.D|X:X::X:X|WORD>",
MATCH_STR
"Match peer address\n"
"IP address of peer\n"
- "IPv6 address of peer\n")
+ "IPv6 address of peer\n"
+ "Interface name of peer\n")
{
int idx_ip = 2;
return bgp_route_match_add(vty, "peer", argv[idx_ip]->arg,
@@ -3172,13 +3192,14 @@ DEFUN (match_peer_local,
DEFUN (no_match_peer,
no_match_peer_cmd,
- "no match peer [<local|A.B.C.D|X:X::X:X>]",
+ "no match peer [<local|A.B.C.D|X:X::X:X|WORD>]",
NO_STR
MATCH_STR
"Match peer address\n"
"Static or Redistributed routes\n"
"IP address of peer\n"
- "IPv6 address of peer\n")
+ "IPv6 address of peer\n"
+ "Interface name of peer\n")
{
int idx_peer = 3;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 749c9d25d4..18190a4f95 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -11334,6 +11334,7 @@ static void bgp_ac_neighbor(vector comps, struct cmd_token *token)
static const struct cmd_variable_handler bgp_var_neighbor[] = {
{.varname = "neighbor", .completions = bgp_ac_neighbor},
{.varname = "neighbors", .completions = bgp_ac_neighbor},
+ {.varname = "peer", .completions = bgp_ac_neighbor},
{.completions = NULL}};
void bgp_vty_init(void)
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 0d1d768294..bec7050226 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1338,12 +1338,14 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, u_short instance)
vrf_bitmap_set(zclient->redist[afi][type], bgp->vrf_id);
}
- /* Don't try to register if we're not connected to Zebra or Zebra
- * doesn't
- * know of this instance.
+ /*
+ * Don't try to register if we're not connected to Zebra or Zebra
+ * doesn't know of this instance.
+ *
+ * When we come up later well resend if needed.
*/
if (!bgp_install_info_to_zebra(bgp))
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_SUCCESS;
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Tx redistribute add VRF %u afi %d %s %d",
diff --git a/doc/routemap.texi b/doc/routemap.texi
index 33062a7f61..69c07357e7 100644
--- a/doc/routemap.texi
+++ b/doc/routemap.texi
@@ -5,8 +5,8 @@ Route maps provide a means to both filter and/or apply actions to
route, hence allowing policy to be applied to routes.
@menu
-* Route Map Command::
-* Route Map Match Command::
+* Route Map Command::
+* Route Map Match Command::
* Route Map Set Command::
* Route Map Call Command::
* Route Map Exit Action Command::
@@ -159,6 +159,22 @@ Matches the specified @var{local-preference}.
Matches the specified @var{community_list}
@end deffn
+@deffn {Route-map Command} {match peer @var{ipv4_addr}} {}
+This is a BGP specific match command. Matches the peer ip address
+if the neighbor was specified in this manner.
+@end deffn
+
+@deffn {Route-map Command} {match peer @var{ipv6_addr}} {}
+This is a BGP specific match command. Matches the peer ipv6
+address if the neighbor was specified in this manner.
+@end deffn
+
+@deffn {Route-map Command} {match peer @var{interface_name}} {}
+This is a BGP specific match command. Matches the peer
+interface name specified if the neighbor was specified
+in this manner.
+@end deffn
+
@node Route Map Set Command
@section Route Map Set Command
diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h
index 3fa59756b7..c5f6e64d0b 100644
--- a/eigrpd/eigrp_const.h
+++ b/eigrpd/eigrp_const.h
@@ -153,14 +153,37 @@ enum eigrp_fsm_states {
#define EIGRP_FSM_NEED_QUERY 2
/*EIGRP FSM events*/
-#define EIGRP_FSM_EVENT_NQ_FCN 0 /*input event other than query from succ, FC not satisfied*/
-#define EIGRP_FSM_EVENT_LR 1 /*last reply, FD is reset*/
-#define EIGRP_FSM_EVENT_Q_FCN 2 /*query from succ, FC not satisfied*/
-#define EIGRP_FSM_EVENT_LR_FCS 3 /*last reply, FC satisfied with current value of FDij*/
-#define EIGRP_FSM_EVENT_DINC 4 /*distance increase while in active state*/
-#define EIGRP_FSM_EVENT_QACT 5 /*query from succ while in active state*/
-#define EIGRP_FSM_EVENT_LR_FCN 6 /*last reply, FC not satisfied with current value of FDij*/
-#define EIGRP_FSM_KEEP_STATE 7 /*state not changed, usually by receiving not last reply */
+enum eigrp_fsm_events {
+ /*
+ * Input event other than query from succ,
+ * FC is not satisified
+ */
+ EIGRP_FSM_EVENT_NQ_FCN,
+
+ /* last reply, FD is reset */
+ EIGRP_FSM_EVENT_LR,
+
+ /* Query from succ, FC not satisfied */
+ EIGRP_FSM_EVENT_Q_FCN,
+
+ /* last reply, FC satisifed with current value of FDij */
+ EIGRP_FSM_EVENT_LR_FCS,
+
+ /* distance increase while in a active state */
+ EIGRP_FSM_EVENT_DINC,
+
+ /* Query from succ while in active state */
+ EIGRP_FSM_EVENT_QACT,
+
+ /* last reply, FC not satisified */
+ EIGRP_FSM_EVENT_LR_FCN,
+
+ /*
+ * state not changed
+ * usually by receiving not last reply
+ */
+ EIGRP_FSM_KEEP_STATE,
+};
/**
* External routes originate from some other protocol - these are them
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c
index 29357c2b24..b4978bc06f 100644
--- a/eigrpd/eigrp_fsm.c
+++ b/eigrpd/eigrp_fsm.c
@@ -170,6 +170,85 @@ struct {
},
};
+static const char *packet_type2str(u_char packet_type)
+{
+ if (packet_type == EIGRP_OPC_UPDATE)
+ return "Update";
+ if (packet_type == EIGRP_OPC_REQUEST)
+ return "Request";
+ if (packet_type == EIGRP_OPC_QUERY)
+ return "Query";
+ if (packet_type == EIGRP_OPC_REPLY)
+ return "Reply";
+ if (packet_type == EIGRP_OPC_HELLO)
+ return "Hello";
+ if (packet_type == EIGRP_OPC_IPXSAP)
+ return "IPXSAP";
+ if (packet_type == EIGRP_OPC_ACK)
+ return "Ack";
+ if (packet_type == EIGRP_OPC_SIAQUERY)
+ return "SIA Query";
+ if (packet_type == EIGRP_OPC_SIAREPLY)
+ return "SIA Reply";
+
+ return "Unknown";
+}
+
+static const char *prefix_state2str(enum eigrp_fsm_states state)
+{
+ switch (state) {
+ case EIGRP_FSM_STATE_PASSIVE:
+ return "Passive";
+ case EIGRP_FSM_STATE_ACTIVE_0:
+ return "Active oij0";
+ case EIGRP_FSM_STATE_ACTIVE_1:
+ return "Active oij1";
+ case EIGRP_FSM_STATE_ACTIVE_2:
+ return "Active oij2";
+ case EIGRP_FSM_STATE_ACTIVE_3:
+ return "Active oij3";
+ }
+
+ return "Unknown";
+}
+
+static const char *fsm_state2str(enum eigrp_fsm_events event)
+{
+ switch (event) {
+ case EIGRP_FSM_KEEP_STATE:
+ return "Keep State Event";
+ case EIGRP_FSM_EVENT_NQ_FCN:
+ return "Non Query Event Feasability not satisfied";
+ case EIGRP_FSM_EVENT_LR:
+ return "Last Reply Event";
+ case EIGRP_FSM_EVENT_Q_FCN:
+ return "Query Event Feasability not satisified";
+ case EIGRP_FSM_EVENT_LR_FCS:
+ return "Last Reply Event Feasability satisified";
+ case EIGRP_FSM_EVENT_DINC:
+ return "Distance Increase Event";
+ case EIGRP_FSM_EVENT_QACT:
+ return "Query from Successor while in active state";
+ case EIGRP_FSM_EVENT_LR_FCN:
+ return "Last Reply Event, Feasibility not satisfied";
+ };
+
+ return "Unknown";
+}
+
+static const char *change2str(enum metric_change change)
+{
+ switch (change) {
+ case METRIC_DECREASE:
+ return "Decrease";
+ case METRIC_SAME:
+ return "Same";
+ case METRIC_INCREASE:
+ return "Increase";
+ }
+
+ return "Unknown";
+}
/*
* Main function in which are make decisions which event occurred.
* msg - argument of type struct eigrp_fsm_action_message contain
@@ -178,7 +257,8 @@ struct {
* Return number of occurred event (arrow in diagram).
*
*/
-static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
+static enum eigrp_fsm_events eigrp_get_fsm_event(
+ struct eigrp_fsm_action_message *msg)
{
// Loading base information from message
// struct eigrp *eigrp = msg->eigrp;
@@ -201,6 +281,9 @@ static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
*/
change = eigrp_topology_update_distance(msg);
+ /* Store for display later */
+ msg->change = change;
+
switch (actual_state) {
case EIGRP_FSM_STATE_PASSIVE: {
struct eigrp_nexthop_entry *head =
@@ -265,7 +348,8 @@ static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
zlog_info("All reply received\n");
return EIGRP_FSM_EVENT_LR;
}
- } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1
+ } else if (msg->packet_type == EIGRP_OPC_UPDATE
+ && change == METRIC_INCREASE
&& (entry->flags
& EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
@@ -310,7 +394,8 @@ static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
zlog_info("All reply received\n");
return EIGRP_FSM_EVENT_LR;
}
- } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1
+ } else if (msg->packet_type == EIGRP_OPC_UPDATE
+ && change == METRIC_INCREASE
&& (entry->flags
& EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
return EIGRP_FSM_EVENT_DINC;
@@ -330,10 +415,15 @@ static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
*/
int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
{
- int event = eigrp_get_fsm_event(msg);
- zlog_info("EIGRP AS: %d State: %d Event: %d Network: %s",
- msg->eigrp->AS, msg->prefix->state, event,
- eigrp_topology_ip_string(msg->prefix));
+ enum eigrp_fsm_events event = eigrp_get_fsm_event(msg);
+
+ zlog_info("EIGRP AS: %d State: %s Event: %s Network: %s Packet Type: %s Reply RIJ Count: %d change: %s",
+ msg->eigrp->AS, prefix_state2str(msg->prefix->state),
+ fsm_state2str(event),
+ eigrp_topology_ip_string(msg->prefix),
+ packet_type2str(msg->packet_type),
+ msg->prefix->rij->count,
+ change2str(msg->change));
(*(NSM[msg->prefix->state][event].func))(msg);
return 1;
diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c
index 83ff194729..5b54f81326 100644
--- a/eigrpd/eigrp_packet.c
+++ b/eigrpd/eigrp_packet.c
@@ -344,8 +344,18 @@ int eigrp_write(struct thread *thread)
/* Get one packet from queue. */
ep = eigrp_fifo_next(ei->obuf);
- assert(ep);
- assert(ep->length >= EIGRP_HEADER_LEN);
+ if (!ep) {
+ zlog_err("%s: Interface %s no packet on queue?",
+ __PRETTY_FUNCTION__, ei->ifp->name);
+ goto out;
+ }
+ if (ep->length < EIGRP_HEADER_LEN) {
+ zlog_err("%s: Packet just has a header?",
+ __PRETTY_FUNCTION__);
+ eigrp_header_dump((struct eigrp_header *)ep->s->data);
+ eigrp_packet_delete(ei);
+ goto out;
+ }
if (ep->dst.s_addr == htonl(EIGRP_MULTICAST_ADDRESS))
eigrp_if_ipmulticast(eigrp, ei->address, ei->ifp->ifindex);
@@ -442,6 +452,7 @@ int eigrp_write(struct thread *thread)
/* Now delete packet from queue. */
eigrp_packet_delete(ei);
+out:
if (eigrp_fifo_next(ei->obuf) == NULL) {
ei->on_write_q = 0;
list_delete_node(eigrp->oi_write_q, node);
diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c
index 88a592e6c9..caa37870a1 100644
--- a/eigrpd/eigrp_query.c
+++ b/eigrpd/eigrp_query.c
@@ -165,7 +165,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
struct listnode *node, *nnode, *node2, *nnode2;
struct eigrp_neighbor *nbr;
struct eigrp_prefix_entry *pe;
- char has_tlv;
+ bool has_tlv = false;
bool ep_saved = false;
ep = eigrp_packet_new(ei->ifp->mtu, NULL);
@@ -180,16 +180,16 @@ void eigrp_send_query(struct eigrp_interface *ei)
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
}
- has_tlv = 0;
for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
nnode, pe)) {
- if (pe->req_action & EIGRP_FSM_NEED_QUERY) {
- length += eigrp_add_internalTLV_to_stream(ep->s, pe);
- for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
- if (nbr->state == EIGRP_NEIGHBOR_UP) {
- listnode_add(pe->rij, nbr);
- has_tlv = 1;
- }
+ if (!(pe->req_action & EIGRP_FSM_NEED_QUERY))
+ continue;
+
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe);
+ for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
+ if (nbr->state == EIGRP_NEIGHBOR_UP) {
+ listnode_add(pe->rij, nbr);
+ has_tlv = true;;
}
}
}
@@ -212,6 +212,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
/*This ack number we await from neighbor*/
ep->sequence_number = ei->eigrp->sequence_number;
+ ei->eigrp->sequence_number++;
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
if (nbr->state == EIGRP_NEIGHBOR_UP) {
diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c
index 8dbd1a5b35..0ccffde72b 100644
--- a/eigrpd/eigrp_reply.c
+++ b/eigrpd/eigrp_reply.c
@@ -149,49 +149,56 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
while (s->endp > s->getp) {
type = stream_getw(s);
- if (type == EIGRP_TLV_IPv4_INT) {
- struct prefix dest_addr;
-
- stream_set_getp(s, s->getp - sizeof(u_int16_t));
-
- tlv = eigrp_read_ipv4_tlv(s);
-
- dest_addr.family = AF_INET;
- dest_addr.u.prefix4 = tlv->destination;
- dest_addr.prefixlen = tlv->prefix_length;
- struct eigrp_prefix_entry *dest =
- eigrp_topology_table_lookup_ipv4(
- eigrp->topology_table, &dest_addr);
- /*
- * Destination must exists
- */
- assert(dest);
-
- struct eigrp_fsm_action_message msg;
- struct eigrp_nexthop_entry *entry =
- eigrp_prefix_entry_lookup(dest->entries, nbr);
-
- if (eigrp_update_prefix_apply(eigrp, ei,
- EIGRP_FILTER_IN,
- &dest_addr)) {
- tlv->metric.delay = EIGRP_MAX_METRIC;
- }
- /*
- * End of filtering
- */
-
- msg.packet_type = EIGRP_OPC_REPLY;
- msg.eigrp = eigrp;
- msg.data_type = EIGRP_INT;
- msg.adv_router = nbr;
- msg.metrics = tlv->metric;
- msg.entry = entry;
- msg.prefix = dest;
- eigrp_fsm_event(&msg);
-
-
- eigrp_IPv4_InternalTLV_free(tlv);
+
+ if (type != EIGRP_TLV_IPv4_INT)
+ continue;
+
+ struct prefix dest_addr;
+
+ stream_set_getp(s, s->getp - sizeof(u_int16_t));
+
+ tlv = eigrp_read_ipv4_tlv(s);
+
+ dest_addr.family = AF_INET;
+ dest_addr.u.prefix4 = tlv->destination;
+ dest_addr.prefixlen = tlv->prefix_length;
+ struct eigrp_prefix_entry *dest =
+ eigrp_topology_table_lookup_ipv4(
+ eigrp->topology_table, &dest_addr);
+ /*
+ * Destination must exists
+ */
+ if (!dest) {
+ char buf[PREFIX_STRLEN];
+ zlog_err("%s: Received prefix %s which we do not know about",
+ __PRETTY_FUNCTION__,
+ prefix2str(&dest_addr, buf, strlen(buf)));
+ continue;
+ }
+
+ struct eigrp_fsm_action_message msg;
+ struct eigrp_nexthop_entry *entry =
+ eigrp_prefix_entry_lookup(dest->entries, nbr);
+
+ if (eigrp_update_prefix_apply(eigrp, ei,
+ EIGRP_FILTER_IN,
+ &dest_addr)) {
+ tlv->metric.delay = EIGRP_MAX_METRIC;
}
+ /*
+ * End of filtering
+ */
+
+ msg.packet_type = EIGRP_OPC_REPLY;
+ msg.eigrp = eigrp;
+ msg.data_type = EIGRP_INT;
+ msg.adv_router = nbr;
+ msg.metrics = tlv->metric;
+ msg.entry = entry;
+ msg.prefix = dest;
+ eigrp_fsm_event(&msg);
+
+ eigrp_IPv4_InternalTLV_free(tlv);
}
eigrp_hello_send_ack(nbr);
}
diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h
index 324181c21e..aae56c8ffe 100644
--- a/eigrpd/eigrp_structs.h
+++ b/eigrpd/eigrp_structs.h
@@ -499,6 +499,7 @@ struct eigrp_fsm_action_message {
struct eigrp_prefix_entry *prefix;
msg_data_t data_type; // internal or external tlv type
struct eigrp_metrics metrics;
+ enum metric_change change;
};
#endif /* _ZEBRA_EIGRP_STRUCTURES_H_ */
diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c
index 42d398458e..fd7a233238 100644
--- a/eigrpd/eigrpd.c
+++ b/eigrpd/eigrpd.c
@@ -284,14 +284,15 @@ void eigrp_finish_final(struct eigrp *eigrp)
list_delete_and_null(&eigrp->eiflist);
list_delete_and_null(&eigrp->oi_write_q);
- list_delete_and_null(&eigrp->topology_changes_externalIPV4);
- list_delete_and_null(&eigrp->topology_changes_internalIPV4);
eigrp_topology_cleanup(eigrp->topology_table);
eigrp_topology_free(eigrp->topology_table);
eigrp_nbr_delete(eigrp->neighbor_self);
+ list_delete_and_null(&eigrp->topology_changes_externalIPV4);
+ list_delete_and_null(&eigrp->topology_changes_internalIPV4);
+
eigrp_delete(eigrp);
XFREE(MTYPE_EIGRP_TOP, eigrp);
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
new file mode 100644
index 0000000000..156f4434ca
--- /dev/null
+++ b/include/linux/if_bridge.h
@@ -0,0 +1,294 @@
+/*
+ * Linux ethernet bridge
+ *
+ * Authors:
+ * Lennert Buytenhek <buytenh@gnu.org>
+ *
+ * This program 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 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_IF_BRIDGE_H
+#define _LINUX_IF_BRIDGE_H
+
+#include <linux/types.h>
+#include <linux/if_ether.h>
+#include <linux/in6.h>
+
+#define SYSFS_BRIDGE_ATTR "bridge"
+#define SYSFS_BRIDGE_FDB "brforward"
+#define SYSFS_BRIDGE_PORT_SUBDIR "brif"
+#define SYSFS_BRIDGE_PORT_ATTR "brport"
+#define SYSFS_BRIDGE_PORT_LINK "bridge"
+
+#define BRCTL_VERSION 1
+
+#define BRCTL_GET_VERSION 0
+#define BRCTL_GET_BRIDGES 1
+#define BRCTL_ADD_BRIDGE 2
+#define BRCTL_DEL_BRIDGE 3
+#define BRCTL_ADD_IF 4
+#define BRCTL_DEL_IF 5
+#define BRCTL_GET_BRIDGE_INFO 6
+#define BRCTL_GET_PORT_LIST 7
+#define BRCTL_SET_BRIDGE_FORWARD_DELAY 8
+#define BRCTL_SET_BRIDGE_HELLO_TIME 9
+#define BRCTL_SET_BRIDGE_MAX_AGE 10
+#define BRCTL_SET_AGEING_TIME 11
+#define BRCTL_SET_GC_INTERVAL 12
+#define BRCTL_GET_PORT_INFO 13
+#define BRCTL_SET_BRIDGE_STP_STATE 14
+#define BRCTL_SET_BRIDGE_PRIORITY 15
+#define BRCTL_SET_PORT_PRIORITY 16
+#define BRCTL_SET_PATH_COST 17
+#define BRCTL_GET_FDB_ENTRIES 18
+
+#define BR_STATE_DISABLED 0
+#define BR_STATE_LISTENING 1
+#define BR_STATE_LEARNING 2
+#define BR_STATE_FORWARDING 3
+#define BR_STATE_BLOCKING 4
+
+struct __bridge_info {
+ __u64 designated_root;
+ __u64 bridge_id;
+ __u32 root_path_cost;
+ __u32 max_age;
+ __u32 hello_time;
+ __u32 forward_delay;
+ __u32 bridge_max_age;
+ __u32 bridge_hello_time;
+ __u32 bridge_forward_delay;
+ __u8 topology_change;
+ __u8 topology_change_detected;
+ __u8 root_port;
+ __u8 stp_enabled;
+ __u32 ageing_time;
+ __u32 gc_interval;
+ __u32 hello_timer_value;
+ __u32 tcn_timer_value;
+ __u32 topology_change_timer_value;
+ __u32 gc_timer_value;
+};
+
+struct __port_info {
+ __u64 designated_root;
+ __u64 designated_bridge;
+ __u16 port_id;
+ __u16 designated_port;
+ __u32 path_cost;
+ __u32 designated_cost;
+ __u8 state;
+ __u8 top_change_ack;
+ __u8 config_pending;
+ __u8 unused0;
+ __u32 message_age_timer_value;
+ __u32 forward_delay_timer_value;
+ __u32 hold_timer_value;
+};
+
+struct __fdb_entry {
+ __u8 mac_addr[ETH_ALEN];
+ __u8 port_no;
+ __u8 is_local;
+ __u32 ageing_timer_value;
+ __u8 port_hi;
+ __u8 pad0;
+ __u16 unused;
+};
+
+/* Bridge Flags */
+#define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */
+#define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */
+
+#define BRIDGE_MODE_VEB 0 /* Default loopback mode */
+#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */
+#define BRIDGE_MODE_UNDEF 0xFFFF /* mode undefined */
+
+/* Bridge management nested attributes
+ * [IFLA_AF_SPEC] = {
+ * [IFLA_BRIDGE_FLAGS]
+ * [IFLA_BRIDGE_MODE]
+ * [IFLA_BRIDGE_VLAN_INFO]
+ * }
+ */
+enum {
+ IFLA_BRIDGE_FLAGS,
+ IFLA_BRIDGE_MODE,
+ IFLA_BRIDGE_VLAN_INFO,
+ IFLA_BRIDGE_VLAN_TUNNEL_INFO,
+ __IFLA_BRIDGE_MAX,
+};
+#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
+
+#define BRIDGE_VLAN_INFO_MASTER (1<<0) /* Operate on Bridge device as well */
+#define BRIDGE_VLAN_INFO_PVID (1<<1) /* VLAN is PVID, ingress untagged */
+#define BRIDGE_VLAN_INFO_UNTAGGED (1<<2) /* VLAN egresses untagged */
+#define BRIDGE_VLAN_INFO_RANGE_BEGIN (1<<3) /* VLAN is start of vlan range */
+#define BRIDGE_VLAN_INFO_RANGE_END (1<<4) /* VLAN is end of vlan range */
+#define BRIDGE_VLAN_INFO_BRENTRY (1<<5) /* Global bridge VLAN entry */
+
+struct bridge_vlan_info {
+ __u16 flags;
+ __u16 vid;
+};
+
+enum {
+ IFLA_BRIDGE_VLAN_TUNNEL_UNSPEC,
+ IFLA_BRIDGE_VLAN_TUNNEL_ID,
+ IFLA_BRIDGE_VLAN_TUNNEL_VID,
+ IFLA_BRIDGE_VLAN_TUNNEL_FLAGS,
+ __IFLA_BRIDGE_VLAN_TUNNEL_MAX,
+};
+
+#define IFLA_BRIDGE_VLAN_TUNNEL_MAX (__IFLA_BRIDGE_VLAN_TUNNEL_MAX - 1)
+
+struct bridge_vlan_xstats {
+ __u64 rx_bytes;
+ __u64 rx_packets;
+ __u64 tx_bytes;
+ __u64 tx_packets;
+ __u16 vid;
+ __u16 flags;
+ __u32 pad2;
+};
+
+/* Bridge multicast database attributes
+ * [MDBA_MDB] = {
+ * [MDBA_MDB_ENTRY] = {
+ * [MDBA_MDB_ENTRY_INFO] {
+ * struct br_mdb_entry
+ * [MDBA_MDB_EATTR attributes]
+ * }
+ * }
+ * }
+ * [MDBA_ROUTER] = {
+ * [MDBA_ROUTER_PORT] = {
+ * u32 ifindex
+ * [MDBA_ROUTER_PATTR attributes]
+ * }
+ * }
+ */
+enum {
+ MDBA_UNSPEC,
+ MDBA_MDB,
+ MDBA_ROUTER,
+ __MDBA_MAX,
+};
+#define MDBA_MAX (__MDBA_MAX - 1)
+
+enum {
+ MDBA_MDB_UNSPEC,
+ MDBA_MDB_ENTRY,
+ __MDBA_MDB_MAX,
+};
+#define MDBA_MDB_MAX (__MDBA_MDB_MAX - 1)
+
+enum {
+ MDBA_MDB_ENTRY_UNSPEC,
+ MDBA_MDB_ENTRY_INFO,
+ __MDBA_MDB_ENTRY_MAX,
+};
+#define MDBA_MDB_ENTRY_MAX (__MDBA_MDB_ENTRY_MAX - 1)
+
+/* per mdb entry additional attributes */
+enum {
+ MDBA_MDB_EATTR_UNSPEC,
+ MDBA_MDB_EATTR_TIMER,
+ __MDBA_MDB_EATTR_MAX
+};
+#define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
+
+/* multicast router types */
+enum {
+ MDB_RTR_TYPE_DISABLED,
+ MDB_RTR_TYPE_TEMP_QUERY,
+ MDB_RTR_TYPE_PERM,
+ MDB_RTR_TYPE_TEMP
+};
+
+enum {
+ MDBA_ROUTER_UNSPEC,
+ MDBA_ROUTER_PORT,
+ __MDBA_ROUTER_MAX,
+};
+#define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1)
+
+/* router port attributes */
+enum {
+ MDBA_ROUTER_PATTR_UNSPEC,
+ MDBA_ROUTER_PATTR_TIMER,
+ MDBA_ROUTER_PATTR_TYPE,
+ __MDBA_ROUTER_PATTR_MAX
+};
+#define MDBA_ROUTER_PATTR_MAX (__MDBA_ROUTER_PATTR_MAX - 1)
+
+struct br_port_msg {
+ __u8 family;
+ __u32 ifindex;
+};
+
+struct br_mdb_entry {
+ __u32 ifindex;
+#define MDB_TEMPORARY 0
+#define MDB_PERMANENT 1
+ __u8 state;
+#define MDB_FLAGS_OFFLOAD (1 << 0)
+ __u8 flags;
+ __u16 vid;
+ struct {
+ union {
+ __be32 ip4;
+ struct in6_addr ip6;
+ } u;
+ __be16 proto;
+ } addr;
+};
+
+enum {
+ MDBA_SET_ENTRY_UNSPEC,
+ MDBA_SET_ENTRY,
+ __MDBA_SET_ENTRY_MAX,
+};
+#define MDBA_SET_ENTRY_MAX (__MDBA_SET_ENTRY_MAX - 1)
+
+/* Embedded inside LINK_XSTATS_TYPE_BRIDGE */
+enum {
+ BRIDGE_XSTATS_UNSPEC,
+ BRIDGE_XSTATS_VLAN,
+ BRIDGE_XSTATS_MCAST,
+ BRIDGE_XSTATS_PAD,
+ __BRIDGE_XSTATS_MAX
+};
+#define BRIDGE_XSTATS_MAX (__BRIDGE_XSTATS_MAX - 1)
+
+enum {
+ BR_MCAST_DIR_RX,
+ BR_MCAST_DIR_TX,
+ BR_MCAST_DIR_SIZE
+};
+
+/* IGMP/MLD statistics */
+struct br_mcast_stats {
+ __u64 igmp_v1queries[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v2queries[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v3queries[BR_MCAST_DIR_SIZE];
+ __u64 igmp_leaves[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v1reports[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v2reports[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v3reports[BR_MCAST_DIR_SIZE];
+ __u64 igmp_parse_errors;
+
+ __u64 mld_v1queries[BR_MCAST_DIR_SIZE];
+ __u64 mld_v2queries[BR_MCAST_DIR_SIZE];
+ __u64 mld_leaves[BR_MCAST_DIR_SIZE];
+ __u64 mld_v1reports[BR_MCAST_DIR_SIZE];
+ __u64 mld_v2reports[BR_MCAST_DIR_SIZE];
+ __u64 mld_parse_errors;
+
+ __u64 mcast_bytes[BR_MCAST_DIR_SIZE];
+ __u64 mcast_packets[BR_MCAST_DIR_SIZE];
+};
+#endif /* _LINUX_IF_BRIDGE_H */
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
new file mode 100644
index 0000000000..1f97d0560b
--- /dev/null
+++ b/include/linux/if_link.h
@@ -0,0 +1,928 @@
+#ifndef _LINUX_IF_LINK_H
+#define _LINUX_IF_LINK_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+/* This struct should be in sync with struct rtnl_link_stats64 */
+struct rtnl_link_stats {
+ __u32 rx_packets; /* total packets received */
+ __u32 tx_packets; /* total packets transmitted */
+ __u32 rx_bytes; /* total bytes received */
+ __u32 tx_bytes; /* total bytes transmitted */
+ __u32 rx_errors; /* bad packets received */
+ __u32 tx_errors; /* packet transmit problems */
+ __u32 rx_dropped; /* no space in linux buffers */
+ __u32 tx_dropped; /* no space available in linux */
+ __u32 multicast; /* multicast packets received */
+ __u32 collisions;
+
+ /* detailed rx_errors: */
+ __u32 rx_length_errors;
+ __u32 rx_over_errors; /* receiver ring buff overflow */
+ __u32 rx_crc_errors; /* recved pkt with crc error */
+ __u32 rx_frame_errors; /* recv'd frame alignment error */
+ __u32 rx_fifo_errors; /* recv'r fifo overrun */
+ __u32 rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ __u32 tx_aborted_errors;
+ __u32 tx_carrier_errors;
+ __u32 tx_fifo_errors;
+ __u32 tx_heartbeat_errors;
+ __u32 tx_window_errors;
+
+ /* for cslip etc */
+ __u32 rx_compressed;
+ __u32 tx_compressed;
+
+ __u32 rx_nohandler; /* dropped, no handler found */
+};
+
+/* The main device statistics structure */
+struct rtnl_link_stats64 {
+ __u64 rx_packets; /* total packets received */
+ __u64 tx_packets; /* total packets transmitted */
+ __u64 rx_bytes; /* total bytes received */
+ __u64 tx_bytes; /* total bytes transmitted */
+ __u64 rx_errors; /* bad packets received */
+ __u64 tx_errors; /* packet transmit problems */
+ __u64 rx_dropped; /* no space in linux buffers */
+ __u64 tx_dropped; /* no space available in linux */
+ __u64 multicast; /* multicast packets received */
+ __u64 collisions;
+
+ /* detailed rx_errors: */
+ __u64 rx_length_errors;
+ __u64 rx_over_errors; /* receiver ring buff overflow */
+ __u64 rx_crc_errors; /* recved pkt with crc error */
+ __u64 rx_frame_errors; /* recv'd frame alignment error */
+ __u64 rx_fifo_errors; /* recv'r fifo overrun */
+ __u64 rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ __u64 tx_aborted_errors;
+ __u64 tx_carrier_errors;
+ __u64 tx_fifo_errors;
+ __u64 tx_heartbeat_errors;
+ __u64 tx_window_errors;
+
+ /* for cslip etc */
+ __u64 rx_compressed;
+ __u64 tx_compressed;
+
+ __u64 rx_nohandler; /* dropped, no handler found */
+};
+
+/* The struct should be in sync with struct ifmap */
+struct rtnl_link_ifmap {
+ __u64 mem_start;
+ __u64 mem_end;
+ __u64 base_addr;
+ __u16 irq;
+ __u8 dma;
+ __u8 port;
+};
+
+/*
+ * IFLA_AF_SPEC
+ * Contains nested attributes for address family specific attributes.
+ * Each address family may create a attribute with the address family
+ * number as type and create its own attribute structure in it.
+ *
+ * Example:
+ * [IFLA_AF_SPEC] = {
+ * [AF_INET] = {
+ * [IFLA_INET_CONF] = ...,
+ * },
+ * [AF_INET6] = {
+ * [IFLA_INET6_FLAGS] = ...,
+ * [IFLA_INET6_CONF] = ...,
+ * }
+ * }
+ */
+
+enum {
+ IFLA_UNSPEC,
+ IFLA_ADDRESS,
+ IFLA_BROADCAST,
+ IFLA_IFNAME,
+ IFLA_MTU,
+ IFLA_LINK,
+ IFLA_QDISC,
+ IFLA_STATS,
+ IFLA_COST,
+#define IFLA_COST IFLA_COST
+ IFLA_PRIORITY,
+#define IFLA_PRIORITY IFLA_PRIORITY
+ IFLA_MASTER,
+#define IFLA_MASTER IFLA_MASTER
+ IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
+#define IFLA_WIRELESS IFLA_WIRELESS
+ IFLA_PROTINFO, /* Protocol specific information for a link */
+#define IFLA_PROTINFO IFLA_PROTINFO
+ IFLA_TXQLEN,
+#define IFLA_TXQLEN IFLA_TXQLEN
+ IFLA_MAP,
+#define IFLA_MAP IFLA_MAP
+ IFLA_WEIGHT,
+#define IFLA_WEIGHT IFLA_WEIGHT
+ IFLA_OPERSTATE,
+ IFLA_LINKMODE,
+ IFLA_LINKINFO,
+#define IFLA_LINKINFO IFLA_LINKINFO
+ IFLA_NET_NS_PID,
+ IFLA_IFALIAS,
+ IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */
+ IFLA_VFINFO_LIST,
+ IFLA_STATS64,
+ IFLA_VF_PORTS,
+ IFLA_PORT_SELF,
+ IFLA_AF_SPEC,
+ IFLA_GROUP, /* Group the device belongs to */
+ IFLA_NET_NS_FD,
+ IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
+ IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */
+#define IFLA_PROMISCUITY IFLA_PROMISCUITY
+ IFLA_NUM_TX_QUEUES,
+ IFLA_NUM_RX_QUEUES,
+ IFLA_CARRIER,
+ IFLA_PHYS_PORT_ID,
+ IFLA_CARRIER_CHANGES,
+ IFLA_PHYS_SWITCH_ID,
+ IFLA_LINK_NETNSID,
+ IFLA_PHYS_PORT_NAME,
+ IFLA_PROTO_DOWN,
+ IFLA_GSO_MAX_SEGS,
+ IFLA_GSO_MAX_SIZE,
+ IFLA_PAD,
+ IFLA_XDP,
+ IFLA_EVENT,
+ __IFLA_MAX
+};
+
+
+#define IFLA_MAX (__IFLA_MAX - 1)
+
+/* backwards compatibility for userspace */
+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+
+enum {
+ IFLA_INET_UNSPEC,
+ IFLA_INET_CONF,
+ __IFLA_INET_MAX,
+};
+
+#define IFLA_INET_MAX (__IFLA_INET_MAX - 1)
+
+/* ifi_flags.
+
+ IFF_* flags.
+
+ The only change is:
+ IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
+ more not changeable by user. They describe link media
+ characteristics and set by device driver.
+
+ Comments:
+ - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
+ - If neither of these three flags are set;
+ the interface is NBMA.
+
+ - IFF_MULTICAST does not mean anything special:
+ multicasts can be used on all not-NBMA links.
+ IFF_MULTICAST means that this media uses special encapsulation
+ for multicast frames. Apparently, all IFF_POINTOPOINT and
+ IFF_BROADCAST devices are able to use multicasts too.
+ */
+
+/* IFLA_LINK.
+ For usual devices it is equal ifi_index.
+ If it is a "virtual interface" (f.e. tunnel), ifi_link
+ can point to real physical interface (f.e. for bandwidth calculations),
+ or maybe 0, what means, that real media is unknown (usual
+ for IPIP tunnels, when route to endpoint is allowed to change)
+ */
+
+/* Subtype attributes for IFLA_PROTINFO */
+enum {
+ IFLA_INET6_UNSPEC,
+ IFLA_INET6_FLAGS, /* link flags */
+ IFLA_INET6_CONF, /* sysctl parameters */
+ IFLA_INET6_STATS, /* statistics */
+ IFLA_INET6_MCAST, /* MC things. What of them? */
+ IFLA_INET6_CACHEINFO, /* time values and max reasm size */
+ IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
+ IFLA_INET6_TOKEN, /* device token */
+ IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+ __IFLA_INET6_MAX
+};
+
+#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
+
+enum in6_addr_gen_mode {
+ IN6_ADDR_GEN_MODE_EUI64,
+ IN6_ADDR_GEN_MODE_NONE,
+ IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
+ IN6_ADDR_GEN_MODE_RANDOM,
+};
+
+/* Bridge section */
+
+enum {
+ IFLA_BR_UNSPEC,
+ IFLA_BR_FORWARD_DELAY,
+ IFLA_BR_HELLO_TIME,
+ IFLA_BR_MAX_AGE,
+ IFLA_BR_AGEING_TIME,
+ IFLA_BR_STP_STATE,
+ IFLA_BR_PRIORITY,
+ IFLA_BR_VLAN_FILTERING,
+ IFLA_BR_VLAN_PROTOCOL,
+ IFLA_BR_GROUP_FWD_MASK,
+ IFLA_BR_ROOT_ID,
+ IFLA_BR_BRIDGE_ID,
+ IFLA_BR_ROOT_PORT,
+ IFLA_BR_ROOT_PATH_COST,
+ IFLA_BR_TOPOLOGY_CHANGE,
+ IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
+ IFLA_BR_HELLO_TIMER,
+ IFLA_BR_TCN_TIMER,
+ IFLA_BR_TOPOLOGY_CHANGE_TIMER,
+ IFLA_BR_GC_TIMER,
+ IFLA_BR_GROUP_ADDR,
+ IFLA_BR_FDB_FLUSH,
+ IFLA_BR_MCAST_ROUTER,
+ IFLA_BR_MCAST_SNOOPING,
+ IFLA_BR_MCAST_QUERY_USE_IFADDR,
+ IFLA_BR_MCAST_QUERIER,
+ IFLA_BR_MCAST_HASH_ELASTICITY,
+ IFLA_BR_MCAST_HASH_MAX,
+ IFLA_BR_MCAST_LAST_MEMBER_CNT,
+ IFLA_BR_MCAST_STARTUP_QUERY_CNT,
+ IFLA_BR_MCAST_LAST_MEMBER_INTVL,
+ IFLA_BR_MCAST_MEMBERSHIP_INTVL,
+ IFLA_BR_MCAST_QUERIER_INTVL,
+ IFLA_BR_MCAST_QUERY_INTVL,
+ IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
+ IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
+ IFLA_BR_NF_CALL_IPTABLES,
+ IFLA_BR_NF_CALL_IP6TABLES,
+ IFLA_BR_NF_CALL_ARPTABLES,
+ IFLA_BR_VLAN_DEFAULT_PVID,
+ IFLA_BR_PAD,
+ IFLA_BR_VLAN_STATS_ENABLED,
+ IFLA_BR_MCAST_STATS_ENABLED,
+ IFLA_BR_MCAST_IGMP_VERSION,
+ IFLA_BR_MCAST_MLD_VERSION,
+ __IFLA_BR_MAX,
+};
+
+#define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
+
+struct ifla_bridge_id {
+ __u8 prio[2];
+ __u8 addr[6]; /* ETH_ALEN */
+};
+
+enum {
+ BRIDGE_MODE_UNSPEC,
+ BRIDGE_MODE_HAIRPIN,
+};
+
+enum {
+ IFLA_BRPORT_UNSPEC,
+ IFLA_BRPORT_STATE, /* Spanning tree state */
+ IFLA_BRPORT_PRIORITY, /* " priority */
+ IFLA_BRPORT_COST, /* " cost */
+ IFLA_BRPORT_MODE, /* mode (hairpin) */
+ IFLA_BRPORT_GUARD, /* bpdu guard */
+ IFLA_BRPORT_PROTECT, /* root port protection */
+ IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */
+ IFLA_BRPORT_LEARNING, /* mac learning */
+ IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */
+ IFLA_BRPORT_PROXYARP, /* proxy ARP */
+ IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */
+ IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */
+ IFLA_BRPORT_ROOT_ID, /* designated root */
+ IFLA_BRPORT_BRIDGE_ID, /* designated bridge */
+ IFLA_BRPORT_DESIGNATED_PORT,
+ IFLA_BRPORT_DESIGNATED_COST,
+ IFLA_BRPORT_ID,
+ IFLA_BRPORT_NO,
+ IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
+ IFLA_BRPORT_CONFIG_PENDING,
+ IFLA_BRPORT_MESSAGE_AGE_TIMER,
+ IFLA_BRPORT_FORWARD_DELAY_TIMER,
+ IFLA_BRPORT_HOLD_TIMER,
+ IFLA_BRPORT_FLUSH,
+ IFLA_BRPORT_MULTICAST_ROUTER,
+ IFLA_BRPORT_PAD,
+ IFLA_BRPORT_MCAST_FLOOD,
+ IFLA_BRPORT_MCAST_TO_UCAST,
+ IFLA_BRPORT_VLAN_TUNNEL,
+ IFLA_BRPORT_BCAST_FLOOD,
+ __IFLA_BRPORT_MAX
+};
+#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
+
+struct ifla_cacheinfo {
+ __u32 max_reasm_len;
+ __u32 tstamp; /* ipv6InterfaceTable updated timestamp */
+ __u32 reachable_time;
+ __u32 retrans_time;
+};
+
+enum {
+ IFLA_INFO_UNSPEC,
+ IFLA_INFO_KIND,
+ IFLA_INFO_DATA,
+ IFLA_INFO_XSTATS,
+ IFLA_INFO_SLAVE_KIND,
+ IFLA_INFO_SLAVE_DATA,
+ __IFLA_INFO_MAX,
+};
+
+#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1)
+
+/* VLAN section */
+
+enum {
+ IFLA_VLAN_UNSPEC,
+ IFLA_VLAN_ID,
+ IFLA_VLAN_FLAGS,
+ IFLA_VLAN_EGRESS_QOS,
+ IFLA_VLAN_INGRESS_QOS,
+ IFLA_VLAN_PROTOCOL,
+ __IFLA_VLAN_MAX,
+};
+
+#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1)
+
+struct ifla_vlan_flags {
+ __u32 flags;
+ __u32 mask;
+};
+
+enum {
+ IFLA_VLAN_QOS_UNSPEC,
+ IFLA_VLAN_QOS_MAPPING,
+ __IFLA_VLAN_QOS_MAX
+};
+
+#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1)
+
+struct ifla_vlan_qos_mapping {
+ __u32 from;
+ __u32 to;
+};
+
+/* MACVLAN section */
+enum {
+ IFLA_MACVLAN_UNSPEC,
+ IFLA_MACVLAN_MODE,
+ IFLA_MACVLAN_FLAGS,
+ IFLA_MACVLAN_MACADDR_MODE,
+ IFLA_MACVLAN_MACADDR,
+ IFLA_MACVLAN_MACADDR_DATA,
+ IFLA_MACVLAN_MACADDR_COUNT,
+ __IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum macvlan_mode {
+ MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
+ MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
+ MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
+ MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
+ MACVLAN_MODE_SOURCE = 16,/* use source MAC address list to assign */
+};
+
+enum macvlan_macaddr_mode {
+ MACVLAN_MACADDR_ADD,
+ MACVLAN_MACADDR_DEL,
+ MACVLAN_MACADDR_FLUSH,
+ MACVLAN_MACADDR_SET,
+};
+
+#define MACVLAN_FLAG_NOPROMISC 1
+
+/* VRF section */
+enum {
+ IFLA_VRF_UNSPEC,
+ IFLA_VRF_TABLE,
+ __IFLA_VRF_MAX
+};
+
+#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
+
+enum {
+ IFLA_VRF_PORT_UNSPEC,
+ IFLA_VRF_PORT_TABLE,
+ __IFLA_VRF_PORT_MAX
+};
+
+#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1)
+
+/* MACSEC section */
+enum {
+ IFLA_MACSEC_UNSPEC,
+ IFLA_MACSEC_SCI,
+ IFLA_MACSEC_PORT,
+ IFLA_MACSEC_ICV_LEN,
+ IFLA_MACSEC_CIPHER_SUITE,
+ IFLA_MACSEC_WINDOW,
+ IFLA_MACSEC_ENCODING_SA,
+ IFLA_MACSEC_ENCRYPT,
+ IFLA_MACSEC_PROTECT,
+ IFLA_MACSEC_INC_SCI,
+ IFLA_MACSEC_ES,
+ IFLA_MACSEC_SCB,
+ IFLA_MACSEC_REPLAY_PROTECT,
+ IFLA_MACSEC_VALIDATION,
+ IFLA_MACSEC_PAD,
+ __IFLA_MACSEC_MAX,
+};
+
+#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
+
+enum macsec_validation_type {
+ MACSEC_VALIDATE_DISABLED = 0,
+ MACSEC_VALIDATE_CHECK = 1,
+ MACSEC_VALIDATE_STRICT = 2,
+ __MACSEC_VALIDATE_END,
+ MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
+};
+
+/* IPVLAN section */
+enum {
+ IFLA_IPVLAN_UNSPEC,
+ IFLA_IPVLAN_MODE,
+ __IFLA_IPVLAN_MAX
+};
+
+#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
+
+enum ipvlan_mode {
+ IPVLAN_MODE_L2 = 0,
+ IPVLAN_MODE_L3,
+ IPVLAN_MODE_L3S,
+ IPVLAN_MODE_MAX
+};
+
+/* VXLAN section */
+enum {
+ IFLA_VXLAN_UNSPEC,
+ IFLA_VXLAN_ID,
+ IFLA_VXLAN_GROUP, /* group or remote address */
+ IFLA_VXLAN_LINK,
+ IFLA_VXLAN_LOCAL,
+ IFLA_VXLAN_TTL,
+ IFLA_VXLAN_TOS,
+ IFLA_VXLAN_LEARNING,
+ IFLA_VXLAN_AGEING,
+ IFLA_VXLAN_LIMIT,
+ IFLA_VXLAN_PORT_RANGE, /* source port */
+ IFLA_VXLAN_PROXY,
+ IFLA_VXLAN_RSC,
+ IFLA_VXLAN_L2MISS,
+ IFLA_VXLAN_L3MISS,
+ IFLA_VXLAN_PORT, /* destination port */
+ IFLA_VXLAN_GROUP6,
+ IFLA_VXLAN_LOCAL6,
+ IFLA_VXLAN_UDP_CSUM,
+ IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
+ IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
+ IFLA_VXLAN_REMCSUM_TX,
+ IFLA_VXLAN_REMCSUM_RX,
+ IFLA_VXLAN_GBP,
+ IFLA_VXLAN_REMCSUM_NOPARTIAL,
+ IFLA_VXLAN_COLLECT_METADATA,
+ IFLA_VXLAN_LABEL,
+ IFLA_VXLAN_GPE,
+ __IFLA_VXLAN_MAX
+};
+#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
+
+struct ifla_vxlan_port_range {
+ __be16 low;
+ __be16 high;
+};
+
+/* GENEVE section */
+enum {
+ IFLA_GENEVE_UNSPEC,
+ IFLA_GENEVE_ID,
+ IFLA_GENEVE_REMOTE,
+ IFLA_GENEVE_TTL,
+ IFLA_GENEVE_TOS,
+ IFLA_GENEVE_PORT, /* destination port */
+ IFLA_GENEVE_COLLECT_METADATA,
+ IFLA_GENEVE_REMOTE6,
+ IFLA_GENEVE_UDP_CSUM,
+ IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
+ IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
+ IFLA_GENEVE_LABEL,
+ __IFLA_GENEVE_MAX
+};
+#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+
+/* PPP section */
+enum {
+ IFLA_PPP_UNSPEC,
+ IFLA_PPP_DEV_FD,
+ __IFLA_PPP_MAX
+};
+#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1)
+
+/* GTP section */
+
+enum ifla_gtp_role {
+ GTP_ROLE_GGSN = 0,
+ GTP_ROLE_SGSN,
+};
+
+enum {
+ IFLA_GTP_UNSPEC,
+ IFLA_GTP_FD0,
+ IFLA_GTP_FD1,
+ IFLA_GTP_PDP_HASHSIZE,
+ IFLA_GTP_ROLE,
+ __IFLA_GTP_MAX,
+};
+#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
+
+/* Bonding section */
+
+enum {
+ IFLA_BOND_UNSPEC,
+ IFLA_BOND_MODE,
+ IFLA_BOND_ACTIVE_SLAVE,
+ IFLA_BOND_MIIMON,
+ IFLA_BOND_UPDELAY,
+ IFLA_BOND_DOWNDELAY,
+ IFLA_BOND_USE_CARRIER,
+ IFLA_BOND_ARP_INTERVAL,
+ IFLA_BOND_ARP_IP_TARGET,
+ IFLA_BOND_ARP_VALIDATE,
+ IFLA_BOND_ARP_ALL_TARGETS,
+ IFLA_BOND_PRIMARY,
+ IFLA_BOND_PRIMARY_RESELECT,
+ IFLA_BOND_FAIL_OVER_MAC,
+ IFLA_BOND_XMIT_HASH_POLICY,
+ IFLA_BOND_RESEND_IGMP,
+ IFLA_BOND_NUM_PEER_NOTIF,
+ IFLA_BOND_ALL_SLAVES_ACTIVE,
+ IFLA_BOND_MIN_LINKS,
+ IFLA_BOND_LP_INTERVAL,
+ IFLA_BOND_PACKETS_PER_SLAVE,
+ IFLA_BOND_AD_LACP_RATE,
+ IFLA_BOND_AD_SELECT,
+ IFLA_BOND_AD_INFO,
+ IFLA_BOND_AD_ACTOR_SYS_PRIO,
+ IFLA_BOND_AD_USER_PORT_KEY,
+ IFLA_BOND_AD_ACTOR_SYSTEM,
+ IFLA_BOND_TLB_DYNAMIC_LB,
+ __IFLA_BOND_MAX,
+};
+
+#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
+
+enum {
+ IFLA_BOND_AD_INFO_UNSPEC,
+ IFLA_BOND_AD_INFO_AGGREGATOR,
+ IFLA_BOND_AD_INFO_NUM_PORTS,
+ IFLA_BOND_AD_INFO_ACTOR_KEY,
+ IFLA_BOND_AD_INFO_PARTNER_KEY,
+ IFLA_BOND_AD_INFO_PARTNER_MAC,
+ __IFLA_BOND_AD_INFO_MAX,
+};
+
+#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1)
+
+enum {
+ IFLA_BOND_SLAVE_UNSPEC,
+ IFLA_BOND_SLAVE_STATE,
+ IFLA_BOND_SLAVE_MII_STATUS,
+ IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
+ IFLA_BOND_SLAVE_PERM_HWADDR,
+ IFLA_BOND_SLAVE_QUEUE_ID,
+ IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
+ IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
+ IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
+ __IFLA_BOND_SLAVE_MAX,
+};
+
+#define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1)
+
+/* SR-IOV virtual function management section */
+
+enum {
+ IFLA_VF_INFO_UNSPEC,
+ IFLA_VF_INFO,
+ __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+ IFLA_VF_UNSPEC,
+ IFLA_VF_MAC, /* Hardware queue specific attributes */
+ IFLA_VF_VLAN, /* VLAN ID and QoS */
+ IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */
+ IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
+ IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */
+ IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */
+ IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query
+ * on/off switch
+ */
+ IFLA_VF_STATS, /* network device statistics */
+ IFLA_VF_TRUST, /* Trust VF */
+ IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
+ IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
+ IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
+ __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
+struct ifla_vf_mac {
+ __u32 vf;
+ __u8 mac[32]; /* MAX_ADDR_LEN */
+};
+
+struct ifla_vf_vlan {
+ __u32 vf;
+ __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+ __u32 qos;
+};
+
+enum {
+ IFLA_VF_VLAN_INFO_UNSPEC,
+ IFLA_VF_VLAN_INFO, /* VLAN ID, QoS and VLAN protocol */
+ __IFLA_VF_VLAN_INFO_MAX,
+};
+
+#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1)
+#define MAX_VLAN_LIST_LEN 1
+
+struct ifla_vf_vlan_info {
+ __u32 vf;
+ __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+ __u32 qos;
+ __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
+};
+
+struct ifla_vf_tx_rate {
+ __u32 vf;
+ __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
+};
+
+struct ifla_vf_rate {
+ __u32 vf;
+ __u32 min_tx_rate; /* Min Bandwidth in Mbps */
+ __u32 max_tx_rate; /* Max Bandwidth in Mbps */
+};
+
+struct ifla_vf_spoofchk {
+ __u32 vf;
+ __u32 setting;
+};
+
+struct ifla_vf_guid {
+ __u32 vf;
+ __u64 guid;
+};
+
+enum {
+ IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */
+ IFLA_VF_LINK_STATE_ENABLE, /* link always up */
+ IFLA_VF_LINK_STATE_DISABLE, /* link always down */
+ __IFLA_VF_LINK_STATE_MAX,
+};
+
+struct ifla_vf_link_state {
+ __u32 vf;
+ __u32 link_state;
+};
+
+struct ifla_vf_rss_query_en {
+ __u32 vf;
+ __u32 setting;
+};
+
+enum {
+ IFLA_VF_STATS_RX_PACKETS,
+ IFLA_VF_STATS_TX_PACKETS,
+ IFLA_VF_STATS_RX_BYTES,
+ IFLA_VF_STATS_TX_BYTES,
+ IFLA_VF_STATS_BROADCAST,
+ IFLA_VF_STATS_MULTICAST,
+ IFLA_VF_STATS_PAD,
+ __IFLA_VF_STATS_MAX,
+};
+
+#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
+
+struct ifla_vf_trust {
+ __u32 vf;
+ __u32 setting;
+};
+
+/* VF ports management section
+ *
+ * Nested layout of set/get msg is:
+ *
+ * [IFLA_NUM_VF]
+ * [IFLA_VF_PORTS]
+ * [IFLA_VF_PORT]
+ * [IFLA_PORT_*], ...
+ * [IFLA_VF_PORT]
+ * [IFLA_PORT_*], ...
+ * ...
+ * [IFLA_PORT_SELF]
+ * [IFLA_PORT_*], ...
+ */
+
+enum {
+ IFLA_VF_PORT_UNSPEC,
+ IFLA_VF_PORT, /* nest */
+ __IFLA_VF_PORT_MAX,
+};
+
+#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
+
+enum {
+ IFLA_PORT_UNSPEC,
+ IFLA_PORT_VF, /* __u32 */
+ IFLA_PORT_PROFILE, /* string */
+ IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */
+ IFLA_PORT_INSTANCE_UUID, /* binary UUID */
+ IFLA_PORT_HOST_UUID, /* binary UUID */
+ IFLA_PORT_REQUEST, /* __u8 */
+ IFLA_PORT_RESPONSE, /* __u16, output only */
+ __IFLA_PORT_MAX,
+};
+
+#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
+
+#define PORT_PROFILE_MAX 40
+#define PORT_UUID_MAX 16
+#define PORT_SELF_VF -1
+
+enum {
+ PORT_REQUEST_PREASSOCIATE = 0,
+ PORT_REQUEST_PREASSOCIATE_RR,
+ PORT_REQUEST_ASSOCIATE,
+ PORT_REQUEST_DISASSOCIATE,
+};
+
+enum {
+ PORT_VDP_RESPONSE_SUCCESS = 0,
+ PORT_VDP_RESPONSE_INVALID_FORMAT,
+ PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_VDP_RESPONSE_UNUSED_VTID,
+ PORT_VDP_RESPONSE_VTID_VIOLATION,
+ PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
+ PORT_VDP_RESPONSE_OUT_OF_SYNC,
+ /* 0x08-0xFF reserved for future VDP use */
+ PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
+ PORT_PROFILE_RESPONSE_INPROGRESS,
+ PORT_PROFILE_RESPONSE_INVALID,
+ PORT_PROFILE_RESPONSE_BADSTATE,
+ PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_PROFILE_RESPONSE_ERROR,
+};
+
+struct ifla_port_vsi {
+ __u8 vsi_mgr_id;
+ __u8 vsi_type_id[3];
+ __u8 vsi_type_version;
+ __u8 pad[3];
+};
+
+
+/* IPoIB section */
+
+enum {
+ IFLA_IPOIB_UNSPEC,
+ IFLA_IPOIB_PKEY,
+ IFLA_IPOIB_MODE,
+ IFLA_IPOIB_UMCAST,
+ __IFLA_IPOIB_MAX
+};
+
+enum {
+ IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */
+ IPOIB_MODE_CONNECTED = 1, /* using connected QPs */
+};
+
+#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
+
+
+/* HSR section */
+
+enum {
+ IFLA_HSR_UNSPEC,
+ IFLA_HSR_SLAVE1,
+ IFLA_HSR_SLAVE2,
+ IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */
+ IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */
+ IFLA_HSR_SEQ_NR,
+ IFLA_HSR_VERSION, /* HSR version */
+ __IFLA_HSR_MAX,
+};
+
+#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+
+/* STATS section */
+
+struct if_stats_msg {
+ __u8 family;
+ __u8 pad1;
+ __u16 pad2;
+ __u32 ifindex;
+ __u32 filter_mask;
+};
+
+/* A stats attribute can be netdev specific or a global stat.
+ * For netdev stats, lets use the prefix IFLA_STATS_LINK_*
+ */
+enum {
+ IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
+ IFLA_STATS_LINK_64,
+ IFLA_STATS_LINK_XSTATS,
+ IFLA_STATS_LINK_XSTATS_SLAVE,
+ IFLA_STATS_LINK_OFFLOAD_XSTATS,
+ IFLA_STATS_AF_SPEC,
+ __IFLA_STATS_MAX,
+};
+
+#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
+
+#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1))
+
+/* These are embedded into IFLA_STATS_LINK_XSTATS:
+ * [IFLA_STATS_LINK_XSTATS]
+ * -> [LINK_XSTATS_TYPE_xxx]
+ * -> [rtnl link type specific attributes]
+ */
+enum {
+ LINK_XSTATS_TYPE_UNSPEC,
+ LINK_XSTATS_TYPE_BRIDGE,
+ __LINK_XSTATS_TYPE_MAX
+};
+#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
+
+/* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */
+enum {
+ IFLA_OFFLOAD_XSTATS_UNSPEC,
+ IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */
+ __IFLA_OFFLOAD_XSTATS_MAX
+};
+#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1)
+
+/* XDP section */
+
+#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
+#define XDP_FLAGS_SKB_MODE (1U << 1)
+#define XDP_FLAGS_DRV_MODE (1U << 2)
+#define XDP_FLAGS_HW_MODE (1U << 3)
+#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \
+ XDP_FLAGS_DRV_MODE | \
+ XDP_FLAGS_HW_MODE)
+#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
+ XDP_FLAGS_MODES)
+
+/* These are stored into IFLA_XDP_ATTACHED on dump. */
+enum {
+ XDP_ATTACHED_NONE = 0,
+ XDP_ATTACHED_DRV,
+ XDP_ATTACHED_SKB,
+ XDP_ATTACHED_HW,
+};
+
+enum {
+ IFLA_XDP_UNSPEC,
+ IFLA_XDP_FD,
+ IFLA_XDP_ATTACHED,
+ IFLA_XDP_FLAGS,
+ IFLA_XDP_PROG_ID,
+ __IFLA_XDP_MAX,
+};
+
+#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
+
+enum {
+ IFLA_EVENT_NONE,
+ IFLA_EVENT_REBOOT, /* internal reset / reboot */
+ IFLA_EVENT_FEATURES, /* change in offload features */
+ IFLA_EVENT_BONDING_FAILOVER, /* change in active slave */
+ IFLA_EVENT_NOTIFY_PEERS, /* re-sent grat. arp/ndisc */
+ IFLA_EVENT_IGMP_RESEND, /* re-sent IGMP JOIN */
+ IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */
+};
+
+#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/lwtunnel.h b/include/linux/lwtunnel.h
new file mode 100644
index 0000000000..3298426271
--- /dev/null
+++ b/include/linux/lwtunnel.h
@@ -0,0 +1,70 @@
+#ifndef _LWTUNNEL_H_
+#define _LWTUNNEL_H_
+
+#include <linux/types.h>
+
+enum lwtunnel_encap_types {
+ LWTUNNEL_ENCAP_NONE,
+ LWTUNNEL_ENCAP_MPLS,
+ LWTUNNEL_ENCAP_IP,
+ LWTUNNEL_ENCAP_ILA,
+ LWTUNNEL_ENCAP_IP6,
+ LWTUNNEL_ENCAP_SEG6,
+ LWTUNNEL_ENCAP_BPF,
+ LWTUNNEL_ENCAP_SEG6_LOCAL,
+ __LWTUNNEL_ENCAP_MAX,
+};
+
+#define LWTUNNEL_ENCAP_MAX (__LWTUNNEL_ENCAP_MAX - 1)
+
+enum lwtunnel_ip_t {
+ LWTUNNEL_IP_UNSPEC,
+ LWTUNNEL_IP_ID,
+ LWTUNNEL_IP_DST,
+ LWTUNNEL_IP_SRC,
+ LWTUNNEL_IP_TTL,
+ LWTUNNEL_IP_TOS,
+ LWTUNNEL_IP_FLAGS,
+ LWTUNNEL_IP_PAD,
+ __LWTUNNEL_IP_MAX,
+};
+
+#define LWTUNNEL_IP_MAX (__LWTUNNEL_IP_MAX - 1)
+
+enum lwtunnel_ip6_t {
+ LWTUNNEL_IP6_UNSPEC,
+ LWTUNNEL_IP6_ID,
+ LWTUNNEL_IP6_DST,
+ LWTUNNEL_IP6_SRC,
+ LWTUNNEL_IP6_HOPLIMIT,
+ LWTUNNEL_IP6_TC,
+ LWTUNNEL_IP6_FLAGS,
+ LWTUNNEL_IP6_PAD,
+ __LWTUNNEL_IP6_MAX,
+};
+
+#define LWTUNNEL_IP6_MAX (__LWTUNNEL_IP6_MAX - 1)
+
+enum {
+ LWT_BPF_PROG_UNSPEC,
+ LWT_BPF_PROG_FD,
+ LWT_BPF_PROG_NAME,
+ __LWT_BPF_PROG_MAX,
+};
+
+#define LWT_BPF_PROG_MAX (__LWT_BPF_PROG_MAX - 1)
+
+enum {
+ LWT_BPF_UNSPEC,
+ LWT_BPF_IN,
+ LWT_BPF_OUT,
+ LWT_BPF_XMIT,
+ LWT_BPF_XMIT_HEADROOM,
+ __LWT_BPF_MAX,
+};
+
+#define LWT_BPF_MAX (__LWT_BPF_MAX - 1)
+
+#define LWT_BPF_MAX_HEADROOM 256
+
+#endif /* _LWTUNNEL_H_ */
diff --git a/include/linux/mpls_iptunnel.h b/include/linux/mpls_iptunnel.h
new file mode 100644
index 0000000000..1a0e57b45a
--- /dev/null
+++ b/include/linux/mpls_iptunnel.h
@@ -0,0 +1,30 @@
+/*
+ * mpls tunnel api
+ *
+ * Authors:
+ * Roopa Prabhu <roopa@cumulusnetworks.com>
+ *
+ * This program 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 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_MPLS_IPTUNNEL_H
+#define _LINUX_MPLS_IPTUNNEL_H
+
+/* MPLS tunnel attributes
+ * [RTA_ENCAP] = {
+ * [MPLS_IPTUNNEL_DST]
+ * [MPLS_IPTUNNEL_TTL]
+ * }
+ */
+enum {
+ MPLS_IPTUNNEL_UNSPEC,
+ MPLS_IPTUNNEL_DST,
+ MPLS_IPTUNNEL_TTL,
+ __MPLS_IPTUNNEL_MAX,
+};
+#define MPLS_IPTUNNEL_MAX (__MPLS_IPTUNNEL_MAX - 1)
+
+#endif /* _LINUX_MPLS_IPTUNNEL_H */
diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h
new file mode 100644
index 0000000000..3199d28980
--- /dev/null
+++ b/include/linux/neighbour.h
@@ -0,0 +1,171 @@
+#ifndef __LINUX_NEIGHBOUR_H
+#define __LINUX_NEIGHBOUR_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+struct ndmsg {
+ __u8 ndm_family;
+ __u8 ndm_pad1;
+ __u16 ndm_pad2;
+ __s32 ndm_ifindex;
+ __u16 ndm_state;
+ __u8 ndm_flags;
+ __u8 ndm_type;
+};
+
+enum {
+ NDA_UNSPEC,
+ NDA_DST,
+ NDA_LLADDR,
+ NDA_CACHEINFO,
+ NDA_PROBES,
+ NDA_VLAN,
+ NDA_PORT,
+ NDA_VNI,
+ NDA_IFINDEX,
+ NDA_MASTER,
+ NDA_LINK_NETNSID,
+ NDA_SRC_VNI,
+ __NDA_MAX
+};
+
+#define NDA_MAX (__NDA_MAX - 1)
+
+/*
+ * Neighbor Cache Entry Flags
+ */
+
+#define NTF_USE 0x01
+#define NTF_SELF 0x02
+#define NTF_MASTER 0x04
+#define NTF_PROXY 0x08 /* == ATF_PUBL */
+#define NTF_EXT_LEARNED 0x10
+#define NTF_OFFLOADED 0x20
+#define NTF_ROUTER 0x80
+
+/*
+ * Neighbor Cache Entry States.
+ */
+
+#define NUD_INCOMPLETE 0x01
+#define NUD_REACHABLE 0x02
+#define NUD_STALE 0x04
+#define NUD_DELAY 0x08
+#define NUD_PROBE 0x10
+#define NUD_FAILED 0x20
+
+/* Dummy states */
+#define NUD_NOARP 0x40
+#define NUD_PERMANENT 0x80
+#define NUD_NONE 0x00
+
+/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change
+ and make no address resolution or NUD.
+ NUD_PERMANENT also cannot be deleted by garbage collectors.
+ */
+
+struct nda_cacheinfo {
+ __u32 ndm_confirmed;
+ __u32 ndm_used;
+ __u32 ndm_updated;
+ __u32 ndm_refcnt;
+};
+
+/*****************************************************************
+ * Neighbour tables specific messages.
+ *
+ * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the
+ * NLM_F_DUMP flag set. Every neighbour table configuration is
+ * spread over multiple messages to avoid running into message
+ * size limits on systems with many interfaces. The first message
+ * in the sequence transports all not device specific data such as
+ * statistics, configuration, and the default parameter set.
+ * This message is followed by 0..n messages carrying device
+ * specific parameter sets.
+ * Although the ordering should be sufficient, NDTA_NAME can be
+ * used to identify sequences. The initial message can be identified
+ * by checking for NDTA_CONFIG. The device specific messages do
+ * not contain this TLV but have NDTPA_IFINDEX set to the
+ * corresponding interface index.
+ *
+ * To change neighbour table attributes, send RTM_SETNEIGHTBL
+ * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3],
+ * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked
+ * otherwise. Device specific parameter sets can be changed by
+ * setting NDTPA_IFINDEX to the interface index of the corresponding
+ * device.
+ ****/
+
+struct ndt_stats {
+ __u64 ndts_allocs;
+ __u64 ndts_destroys;
+ __u64 ndts_hash_grows;
+ __u64 ndts_res_failed;
+ __u64 ndts_lookups;
+ __u64 ndts_hits;
+ __u64 ndts_rcv_probes_mcast;
+ __u64 ndts_rcv_probes_ucast;
+ __u64 ndts_periodic_gc_runs;
+ __u64 ndts_forced_gc_runs;
+ __u64 ndts_table_fulls;
+};
+
+enum {
+ NDTPA_UNSPEC,
+ NDTPA_IFINDEX, /* u32, unchangeable */
+ NDTPA_REFCNT, /* u32, read-only */
+ NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */
+ NDTPA_BASE_REACHABLE_TIME, /* u64, msecs */
+ NDTPA_RETRANS_TIME, /* u64, msecs */
+ NDTPA_GC_STALETIME, /* u64, msecs */
+ NDTPA_DELAY_PROBE_TIME, /* u64, msecs */
+ NDTPA_QUEUE_LEN, /* u32 */
+ NDTPA_APP_PROBES, /* u32 */
+ NDTPA_UCAST_PROBES, /* u32 */
+ NDTPA_MCAST_PROBES, /* u32 */
+ NDTPA_ANYCAST_DELAY, /* u64, msecs */
+ NDTPA_PROXY_DELAY, /* u64, msecs */
+ NDTPA_PROXY_QLEN, /* u32 */
+ NDTPA_LOCKTIME, /* u64, msecs */
+ NDTPA_QUEUE_LENBYTES, /* u32 */
+ NDTPA_MCAST_REPROBES, /* u32 */
+ NDTPA_PAD,
+ __NDTPA_MAX
+};
+#define NDTPA_MAX (__NDTPA_MAX - 1)
+
+struct ndtmsg {
+ __u8 ndtm_family;
+ __u8 ndtm_pad1;
+ __u16 ndtm_pad2;
+};
+
+struct ndt_config {
+ __u16 ndtc_key_len;
+ __u16 ndtc_entry_size;
+ __u32 ndtc_entries;
+ __u32 ndtc_last_flush; /* delta to now in msecs */
+ __u32 ndtc_last_rand; /* delta to now in msecs */
+ __u32 ndtc_hash_rnd;
+ __u32 ndtc_hash_mask;
+ __u32 ndtc_hash_chain_gc;
+ __u32 ndtc_proxy_qlen;
+};
+
+enum {
+ NDTA_UNSPEC,
+ NDTA_NAME, /* char *, unchangeable */
+ NDTA_THRESH1, /* u32 */
+ NDTA_THRESH2, /* u32 */
+ NDTA_THRESH3, /* u32 */
+ NDTA_CONFIG, /* struct ndt_config, read-only */
+ NDTA_PARMS, /* nested TLV NDTPA_* */
+ NDTA_STATS, /* struct ndt_stats, read-only */
+ NDTA_GC_INTERVAL, /* u64, msecs */
+ NDTA_PAD,
+ __NDTA_MAX
+};
+#define NDTA_MAX (__NDTA_MAX - 1)
+
+#endif
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
new file mode 100644
index 0000000000..813e9e0767
--- /dev/null
+++ b/include/linux/rtnetlink.h
@@ -0,0 +1,718 @@
+#ifndef __LINUX_RTNETLINK_H
+#define __LINUX_RTNETLINK_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+#include <linux/if_link.h>
+#include <linux/if_addr.h>
+#include <linux/neighbour.h>
+
+/* rtnetlink families. Values up to 127 are reserved for real address
+ * families, values above 128 may be used arbitrarily.
+ */
+#define RTNL_FAMILY_IPMR 128
+#define RTNL_FAMILY_IP6MR 129
+#define RTNL_FAMILY_MAX 129
+
+/****
+ * Routing/neighbour discovery messages.
+ ****/
+
+/* Types of messages */
+
+enum {
+ RTM_BASE = 16,
+#define RTM_BASE RTM_BASE
+
+ RTM_NEWLINK = 16,
+#define RTM_NEWLINK RTM_NEWLINK
+ RTM_DELLINK,
+#define RTM_DELLINK RTM_DELLINK
+ RTM_GETLINK,
+#define RTM_GETLINK RTM_GETLINK
+ RTM_SETLINK,
+#define RTM_SETLINK RTM_SETLINK
+
+ RTM_NEWADDR = 20,
+#define RTM_NEWADDR RTM_NEWADDR
+ RTM_DELADDR,
+#define RTM_DELADDR RTM_DELADDR
+ RTM_GETADDR,
+#define RTM_GETADDR RTM_GETADDR
+
+ RTM_NEWROUTE = 24,
+#define RTM_NEWROUTE RTM_NEWROUTE
+ RTM_DELROUTE,
+#define RTM_DELROUTE RTM_DELROUTE
+ RTM_GETROUTE,
+#define RTM_GETROUTE RTM_GETROUTE
+
+ RTM_NEWNEIGH = 28,
+#define RTM_NEWNEIGH RTM_NEWNEIGH
+ RTM_DELNEIGH,
+#define RTM_DELNEIGH RTM_DELNEIGH
+ RTM_GETNEIGH,
+#define RTM_GETNEIGH RTM_GETNEIGH
+
+ RTM_NEWRULE = 32,
+#define RTM_NEWRULE RTM_NEWRULE
+ RTM_DELRULE,
+#define RTM_DELRULE RTM_DELRULE
+ RTM_GETRULE,
+#define RTM_GETRULE RTM_GETRULE
+
+ RTM_NEWQDISC = 36,
+#define RTM_NEWQDISC RTM_NEWQDISC
+ RTM_DELQDISC,
+#define RTM_DELQDISC RTM_DELQDISC
+ RTM_GETQDISC,
+#define RTM_GETQDISC RTM_GETQDISC
+
+ RTM_NEWTCLASS = 40,
+#define RTM_NEWTCLASS RTM_NEWTCLASS
+ RTM_DELTCLASS,
+#define RTM_DELTCLASS RTM_DELTCLASS
+ RTM_GETTCLASS,
+#define RTM_GETTCLASS RTM_GETTCLASS
+
+ RTM_NEWTFILTER = 44,
+#define RTM_NEWTFILTER RTM_NEWTFILTER
+ RTM_DELTFILTER,
+#define RTM_DELTFILTER RTM_DELTFILTER
+ RTM_GETTFILTER,
+#define RTM_GETTFILTER RTM_GETTFILTER
+
+ RTM_NEWACTION = 48,
+#define RTM_NEWACTION RTM_NEWACTION
+ RTM_DELACTION,
+#define RTM_DELACTION RTM_DELACTION
+ RTM_GETACTION,
+#define RTM_GETACTION RTM_GETACTION
+
+ RTM_NEWPREFIX = 52,
+#define RTM_NEWPREFIX RTM_NEWPREFIX
+
+ RTM_GETMULTICAST = 58,
+#define RTM_GETMULTICAST RTM_GETMULTICAST
+
+ RTM_GETANYCAST = 62,
+#define RTM_GETANYCAST RTM_GETANYCAST
+
+ RTM_NEWNEIGHTBL = 64,
+#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL
+ RTM_GETNEIGHTBL = 66,
+#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL
+ RTM_SETNEIGHTBL,
+#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
+
+ RTM_NEWNDUSEROPT = 68,
+#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
+
+ RTM_NEWADDRLABEL = 72,
+#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
+ RTM_DELADDRLABEL,
+#define RTM_DELADDRLABEL RTM_DELADDRLABEL
+ RTM_GETADDRLABEL,
+#define RTM_GETADDRLABEL RTM_GETADDRLABEL
+
+ RTM_GETDCB = 78,
+#define RTM_GETDCB RTM_GETDCB
+ RTM_SETDCB,
+#define RTM_SETDCB RTM_SETDCB
+
+ RTM_NEWNETCONF = 80,
+#define RTM_NEWNETCONF RTM_NEWNETCONF
+ RTM_DELNETCONF,
+#define RTM_DELNETCONF RTM_DELNETCONF
+ RTM_GETNETCONF = 82,
+#define RTM_GETNETCONF RTM_GETNETCONF
+
+ RTM_NEWMDB = 84,
+#define RTM_NEWMDB RTM_NEWMDB
+ RTM_DELMDB = 85,
+#define RTM_DELMDB RTM_DELMDB
+ RTM_GETMDB = 86,
+#define RTM_GETMDB RTM_GETMDB
+
+ RTM_NEWNSID = 88,
+#define RTM_NEWNSID RTM_NEWNSID
+ RTM_DELNSID = 89,
+#define RTM_DELNSID RTM_DELNSID
+ RTM_GETNSID = 90,
+#define RTM_GETNSID RTM_GETNSID
+
+ RTM_NEWSTATS = 92,
+#define RTM_NEWSTATS RTM_NEWSTATS
+ RTM_GETSTATS = 94,
+#define RTM_GETSTATS RTM_GETSTATS
+
+ RTM_NEWCACHEREPORT = 96,
+#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
+
+ __RTM_MAX,
+#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
+};
+
+#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
+#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
+#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
+
+/*
+ Generic structure for encapsulation of optional route information.
+ It is reminiscent of sockaddr, but with sa_family replaced
+ with attribute type.
+ */
+
+struct rtattr {
+ unsigned short rta_len;
+ unsigned short rta_type;
+};
+
+/* Macros to handle rtattributes */
+
+#define RTA_ALIGNTO 4U
+#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
+#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
+ (rta)->rta_len >= sizeof(struct rtattr) && \
+ (rta)->rta_len <= (len))
+#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
+ (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
+#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
+#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
+#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
+#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
+
+
+
+
+/******************************************************************************
+ * Definitions used in routing table administration.
+ ****/
+
+struct rtmsg {
+ unsigned char rtm_family;
+ unsigned char rtm_dst_len;
+ unsigned char rtm_src_len;
+ unsigned char rtm_tos;
+
+ unsigned char rtm_table; /* Routing table id */
+ unsigned char rtm_protocol; /* Routing protocol; see below */
+ unsigned char rtm_scope; /* See below */
+ unsigned char rtm_type; /* See below */
+
+ unsigned rtm_flags;
+};
+
+/* rtm_type */
+
+enum {
+ RTN_UNSPEC,
+ RTN_UNICAST, /* Gateway or direct route */
+ RTN_LOCAL, /* Accept locally */
+ RTN_BROADCAST, /* Accept locally as broadcast,
+ send as broadcast */
+ RTN_ANYCAST, /* Accept locally as broadcast,
+ but send as unicast */
+ RTN_MULTICAST, /* Multicast route */
+ RTN_BLACKHOLE, /* Drop */
+ RTN_UNREACHABLE, /* Destination is unreachable */
+ RTN_PROHIBIT, /* Administratively prohibited */
+ RTN_THROW, /* Not in this table */
+ RTN_NAT, /* Translate this address */
+ RTN_XRESOLVE, /* Use external resolver */
+ __RTN_MAX
+};
+
+#define RTN_MAX (__RTN_MAX - 1)
+
+
+/* rtm_protocol */
+
+#define RTPROT_UNSPEC 0
+#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects;
+ not used by current IPv4 */
+#define RTPROT_KERNEL 2 /* Route installed by kernel */
+#define RTPROT_BOOT 3 /* Route installed during boot */
+#define RTPROT_STATIC 4 /* Route installed by administrator */
+
+/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
+ they are just passed from user and back as is.
+ It will be used by hypothetical multiple routing daemons.
+ Note that protocol values should be standardized in order to
+ avoid conflicts.
+ */
+
+#define RTPROT_GATED 8 /* Apparently, GateD */
+#define RTPROT_RA 9 /* RDISC/ND router advertisements */
+#define RTPROT_MRT 10 /* Merit MRT */
+#define RTPROT_ZEBRA 11 /* Zebra */
+#define RTPROT_BIRD 12 /* BIRD */
+#define RTPROT_DNROUTED 13 /* DECnet routing daemon */
+#define RTPROT_XORP 14 /* XORP */
+#define RTPROT_NTK 15 /* Netsukuku */
+#define RTPROT_DHCP 16 /* DHCP client */
+#define RTPROT_MROUTED 17 /* Multicast daemon */
+#define RTPROT_BABEL 42 /* Babel daemon */
+
+/* rtm_scope
+
+ Really it is not scope, but sort of distance to the destination.
+ NOWHERE are reserved for not existing destinations, HOST is our
+ local addresses, LINK are destinations, located on directly attached
+ link and UNIVERSE is everywhere in the Universe.
+
+ Intermediate values are also possible f.e. interior routes
+ could be assigned a value between UNIVERSE and LINK.
+*/
+
+enum rt_scope_t {
+ RT_SCOPE_UNIVERSE=0,
+/* User defined values */
+ RT_SCOPE_SITE=200,
+ RT_SCOPE_LINK=253,
+ RT_SCOPE_HOST=254,
+ RT_SCOPE_NOWHERE=255
+};
+
+/* rtm_flags */
+
+#define RTM_F_NOTIFY 0x100 /* Notify user of route change */
+#define RTM_F_CLONED 0x200 /* This route is cloned */
+#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */
+#define RTM_F_PREFIX 0x800 /* Prefix addresses */
+#define RTM_F_LOOKUP_TABLE 0x1000 /* set rtm_table to FIB lookup result */
+#define RTM_F_FIB_MATCH 0x2000 /* return full fib lookup match */
+
+/* Reserved table identifiers */
+
+enum rt_class_t {
+ RT_TABLE_UNSPEC=0,
+/* User defined values */
+ RT_TABLE_COMPAT=252,
+ RT_TABLE_DEFAULT=253,
+ RT_TABLE_MAIN=254,
+ RT_TABLE_LOCAL=255,
+ RT_TABLE_MAX=0xFFFFFFFF
+};
+
+
+/* Routing message attributes */
+
+enum rtattr_type_t {
+ RTA_UNSPEC,
+ RTA_DST,
+ RTA_SRC,
+ RTA_IIF,
+ RTA_OIF,
+ RTA_GATEWAY,
+ RTA_PRIORITY,
+ RTA_PREFSRC,
+ RTA_METRICS,
+ RTA_MULTIPATH,
+ RTA_PROTOINFO, /* no longer used */
+ RTA_FLOW,
+ RTA_CACHEINFO,
+ RTA_SESSION, /* no longer used */
+ RTA_MP_ALGO, /* no longer used */
+ RTA_TABLE,
+ RTA_MARK,
+ RTA_MFC_STATS,
+ RTA_VIA,
+ RTA_NEWDST,
+ RTA_PREF,
+ RTA_ENCAP_TYPE,
+ RTA_ENCAP,
+ RTA_EXPIRES,
+ RTA_PAD,
+ RTA_UID,
+ RTA_TTL_PROPAGATE,
+ __RTA_MAX
+};
+
+#define RTA_MAX (__RTA_MAX - 1)
+
+#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
+#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
+
+/* RTM_MULTIPATH --- array of struct rtnexthop.
+ *
+ * "struct rtnexthop" describes all necessary nexthop information,
+ * i.e. parameters of path to a destination via this nexthop.
+ *
+ * At the moment it is impossible to set different prefsrc, mtu, window
+ * and rtt for different paths from multipath.
+ */
+
+struct rtnexthop {
+ unsigned short rtnh_len;
+ unsigned char rtnh_flags;
+ unsigned char rtnh_hops;
+ int rtnh_ifindex;
+};
+
+/* rtnh_flags */
+
+#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
+#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
+#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
+#define RTNH_F_OFFLOAD 8 /* offloaded route */
+#define RTNH_F_LINKDOWN 16 /* carrier-down on nexthop */
+#define RTNH_F_UNRESOLVED 32 /* The entry is unresolved (ipmr) */
+
+#define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD)
+
+/* Macros to handle hexthops */
+
+#define RTNH_ALIGNTO 4
+#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
+#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
+ ((int)(rtnh)->rtnh_len) <= (len))
+#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
+#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
+#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
+#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
+
+/* RTA_VIA */
+struct rtvia {
+ __kernel_sa_family_t rtvia_family;
+ __u8 rtvia_addr[0];
+};
+
+/* RTM_CACHEINFO */
+
+struct rta_cacheinfo {
+ __u32 rta_clntref;
+ __u32 rta_lastuse;
+ __s32 rta_expires;
+ __u32 rta_error;
+ __u32 rta_used;
+
+#define RTNETLINK_HAVE_PEERINFO 1
+ __u32 rta_id;
+ __u32 rta_ts;
+ __u32 rta_tsage;
+};
+
+/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
+
+enum {
+ RTAX_UNSPEC,
+#define RTAX_UNSPEC RTAX_UNSPEC
+ RTAX_LOCK,
+#define RTAX_LOCK RTAX_LOCK
+ RTAX_MTU,
+#define RTAX_MTU RTAX_MTU
+ RTAX_WINDOW,
+#define RTAX_WINDOW RTAX_WINDOW
+ RTAX_RTT,
+#define RTAX_RTT RTAX_RTT
+ RTAX_RTTVAR,
+#define RTAX_RTTVAR RTAX_RTTVAR
+ RTAX_SSTHRESH,
+#define RTAX_SSTHRESH RTAX_SSTHRESH
+ RTAX_CWND,
+#define RTAX_CWND RTAX_CWND
+ RTAX_ADVMSS,
+#define RTAX_ADVMSS RTAX_ADVMSS
+ RTAX_REORDERING,
+#define RTAX_REORDERING RTAX_REORDERING
+ RTAX_HOPLIMIT,
+#define RTAX_HOPLIMIT RTAX_HOPLIMIT
+ RTAX_INITCWND,
+#define RTAX_INITCWND RTAX_INITCWND
+ RTAX_FEATURES,
+#define RTAX_FEATURES RTAX_FEATURES
+ RTAX_RTO_MIN,
+#define RTAX_RTO_MIN RTAX_RTO_MIN
+ RTAX_INITRWND,
+#define RTAX_INITRWND RTAX_INITRWND
+ RTAX_QUICKACK,
+#define RTAX_QUICKACK RTAX_QUICKACK
+ RTAX_CC_ALGO,
+#define RTAX_CC_ALGO RTAX_CC_ALGO
+ __RTAX_MAX
+};
+
+#define RTAX_MAX (__RTAX_MAX - 1)
+
+#define RTAX_FEATURE_ECN (1 << 0)
+#define RTAX_FEATURE_SACK (1 << 1)
+#define RTAX_FEATURE_TIMESTAMP (1 << 2)
+#define RTAX_FEATURE_ALLFRAG (1 << 3)
+
+#define RTAX_FEATURE_MASK (RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | \
+ RTAX_FEATURE_TIMESTAMP | RTAX_FEATURE_ALLFRAG)
+
+struct rta_session {
+ __u8 proto;
+ __u8 pad1;
+ __u16 pad2;
+
+ union {
+ struct {
+ __u16 sport;
+ __u16 dport;
+ } ports;
+
+ struct {
+ __u8 type;
+ __u8 code;
+ __u16 ident;
+ } icmpt;
+
+ __u32 spi;
+ } u;
+};
+
+struct rta_mfc_stats {
+ __u64 mfcs_packets;
+ __u64 mfcs_bytes;
+ __u64 mfcs_wrong_if;
+};
+
+/****
+ * General form of address family dependent message.
+ ****/
+
+struct rtgenmsg {
+ unsigned char rtgen_family;
+};
+
+/*****************************************************************
+ * Link layer specific messages.
+ ****/
+
+/* struct ifinfomsg
+ * passes link level specific information, not dependent
+ * on network protocol.
+ */
+
+struct ifinfomsg {
+ unsigned char ifi_family;
+ unsigned char __ifi_pad;
+ unsigned short ifi_type; /* ARPHRD_* */
+ int ifi_index; /* Link index */
+ unsigned ifi_flags; /* IFF_* flags */
+ unsigned ifi_change; /* IFF_* change mask */
+};
+
+/********************************************************************
+ * prefix information
+ ****/
+
+struct prefixmsg {
+ unsigned char prefix_family;
+ unsigned char prefix_pad1;
+ unsigned short prefix_pad2;
+ int prefix_ifindex;
+ unsigned char prefix_type;
+ unsigned char prefix_len;
+ unsigned char prefix_flags;
+ unsigned char prefix_pad3;
+};
+
+enum
+{
+ PREFIX_UNSPEC,
+ PREFIX_ADDRESS,
+ PREFIX_CACHEINFO,
+ __PREFIX_MAX
+};
+
+#define PREFIX_MAX (__PREFIX_MAX - 1)
+
+struct prefix_cacheinfo {
+ __u32 preferred_time;
+ __u32 valid_time;
+};
+
+
+/*****************************************************************
+ * Traffic control messages.
+ ****/
+
+struct tcmsg {
+ unsigned char tcm_family;
+ unsigned char tcm__pad1;
+ unsigned short tcm__pad2;
+ int tcm_ifindex;
+ __u32 tcm_handle;
+ __u32 tcm_parent;
+ __u32 tcm_info;
+};
+
+enum {
+ TCA_UNSPEC,
+ TCA_KIND,
+ TCA_OPTIONS,
+ TCA_STATS,
+ TCA_XSTATS,
+ TCA_RATE,
+ TCA_FCNT,
+ TCA_STATS2,
+ TCA_STAB,
+ TCA_PAD,
+ TCA_DUMP_INVISIBLE,
+ TCA_CHAIN,
+ __TCA_MAX
+};
+
+#define TCA_MAX (__TCA_MAX - 1)
+
+#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
+#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
+
+/********************************************************************
+ * Neighbor Discovery userland options
+ ****/
+
+struct nduseroptmsg {
+ unsigned char nduseropt_family;
+ unsigned char nduseropt_pad1;
+ unsigned short nduseropt_opts_len; /* Total length of options */
+ int nduseropt_ifindex;
+ __u8 nduseropt_icmp_type;
+ __u8 nduseropt_icmp_code;
+ unsigned short nduseropt_pad2;
+ unsigned int nduseropt_pad3;
+ /* Followed by one or more ND options */
+};
+
+enum {
+ NDUSEROPT_UNSPEC,
+ NDUSEROPT_SRCADDR,
+ __NDUSEROPT_MAX
+};
+
+#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
+
+/* RTnetlink multicast groups - backwards compatibility for userspace */
+#define RTMGRP_LINK 1
+#define RTMGRP_NOTIFY 2
+#define RTMGRP_NEIGH 4
+#define RTMGRP_TC 8
+
+#define RTMGRP_IPV4_IFADDR 0x10
+#define RTMGRP_IPV4_MROUTE 0x20
+#define RTMGRP_IPV4_ROUTE 0x40
+#define RTMGRP_IPV4_RULE 0x80
+
+#define RTMGRP_IPV6_IFADDR 0x100
+#define RTMGRP_IPV6_MROUTE 0x200
+#define RTMGRP_IPV6_ROUTE 0x400
+#define RTMGRP_IPV6_IFINFO 0x800
+
+#define RTMGRP_DECnet_IFADDR 0x1000
+#define RTMGRP_DECnet_ROUTE 0x4000
+
+#define RTMGRP_IPV6_PREFIX 0x20000
+
+/* RTnetlink multicast groups */
+enum rtnetlink_groups {
+ RTNLGRP_NONE,
+#define RTNLGRP_NONE RTNLGRP_NONE
+ RTNLGRP_LINK,
+#define RTNLGRP_LINK RTNLGRP_LINK
+ RTNLGRP_NOTIFY,
+#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
+ RTNLGRP_NEIGH,
+#define RTNLGRP_NEIGH RTNLGRP_NEIGH
+ RTNLGRP_TC,
+#define RTNLGRP_TC RTNLGRP_TC
+ RTNLGRP_IPV4_IFADDR,
+#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
+ RTNLGRP_IPV4_MROUTE,
+#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
+ RTNLGRP_IPV4_ROUTE,
+#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
+ RTNLGRP_IPV4_RULE,
+#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
+ RTNLGRP_IPV6_IFADDR,
+#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
+ RTNLGRP_IPV6_MROUTE,
+#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
+ RTNLGRP_IPV6_ROUTE,
+#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
+ RTNLGRP_IPV6_IFINFO,
+#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
+ RTNLGRP_DECnet_IFADDR,
+#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
+ RTNLGRP_NOP2,
+ RTNLGRP_DECnet_ROUTE,
+#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
+ RTNLGRP_DECnet_RULE,
+#define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE
+ RTNLGRP_NOP4,
+ RTNLGRP_IPV6_PREFIX,
+#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
+ RTNLGRP_IPV6_RULE,
+#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
+ RTNLGRP_ND_USEROPT,
+#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
+ RTNLGRP_PHONET_IFADDR,
+#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
+ RTNLGRP_PHONET_ROUTE,
+#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
+ RTNLGRP_DCB,
+#define RTNLGRP_DCB RTNLGRP_DCB
+ RTNLGRP_IPV4_NETCONF,
+#define RTNLGRP_IPV4_NETCONF RTNLGRP_IPV4_NETCONF
+ RTNLGRP_IPV6_NETCONF,
+#define RTNLGRP_IPV6_NETCONF RTNLGRP_IPV6_NETCONF
+ RTNLGRP_MDB,
+#define RTNLGRP_MDB RTNLGRP_MDB
+ RTNLGRP_MPLS_ROUTE,
+#define RTNLGRP_MPLS_ROUTE RTNLGRP_MPLS_ROUTE
+ RTNLGRP_NSID,
+#define RTNLGRP_NSID RTNLGRP_NSID
+ RTNLGRP_MPLS_NETCONF,
+#define RTNLGRP_MPLS_NETCONF RTNLGRP_MPLS_NETCONF
+ RTNLGRP_IPV4_MROUTE_R,
+#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
+ RTNLGRP_IPV6_MROUTE_R,
+#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
+ __RTNLGRP_MAX
+};
+#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
+
+/* TC action piece */
+struct tcamsg {
+ unsigned char tca_family;
+ unsigned char tca__pad1;
+ unsigned short tca__pad2;
+};
+
+enum {
+ TCA_ROOT_UNSPEC,
+ TCA_ROOT_TAB,
+#define TCA_ACT_TAB TCA_ROOT_TAB
+#define TCAA_MAX TCA_ROOT_TAB
+ TCA_ROOT_FLAGS,
+ TCA_ROOT_COUNT,
+ TCA_ROOT_TIME_DELTA, /* in msecs */
+ __TCA_ROOT_MAX,
+#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
+};
+
+#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
+#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
+/* tcamsg flags stored in attribute TCA_ROOT_FLAGS
+ *
+ * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO
+ * actions in a dump. All dump responses will contain the number of actions
+ * being dumped stored in for user app's consumption in TCA_ROOT_COUNT
+ *
+ */
+#define TCA_FLAG_LARGE_DUMP_ON (1 << 0)
+
+/* New extended info filters for IFLA_EXT_MASK */
+#define RTEXT_FILTER_VF (1 << 0)
+#define RTEXT_FILTER_BRVLAN (1 << 1)
+#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)
+#define RTEXT_FILTER_SKIP_STATS (1 << 3)
+
+/* End of information exported to user level */
+
+
+
+#endif /* __LINUX_RTNETLINK_H */
diff --git a/include/linux/socket.h b/include/linux/socket.h
new file mode 100644
index 0000000000..8c1e501774
--- /dev/null
+++ b/include/linux/socket.h
@@ -0,0 +1,21 @@
+#ifndef _LINUX_SOCKET_H
+#define _LINUX_SOCKET_H
+
+/*
+ * Desired design of maximum size and alignment (see RFC2553)
+ */
+#define _K_SS_MAXSIZE 128 /* Implementation specific max size */
+#define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *))
+ /* Implementation specific desired alignment */
+
+typedef unsigned short __kernel_sa_family_t;
+
+struct __kernel_sockaddr_storage {
+ __kernel_sa_family_t ss_family; /* address family */
+ /* Following field(s) are implementation specific */
+ char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+ /* space to achieve desired size, */
+ /* _SS_MAXSIZE value minus size of ss_family */
+} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */
+
+#endif /* _LINUX_SOCKET_H */
diff --git a/include/subdir.am b/include/subdir.am
new file mode 100644
index 0000000000..98bd148002
--- /dev/null
+++ b/include/subdir.am
@@ -0,0 +1,9 @@
+noinst_HEADERS += \
+ include/linux/if_bridge.h \
+ include/linux/if_link.h \
+ include/linux/lwtunnel.h \
+ include/linux/mpls_iptunnel.h \
+ include/linux/neighbour.h \
+ include/linux/rtnetlink.h \
+ include/linux/socket.h \
+ # end
diff --git a/lib/vrf.h b/lib/vrf.h
index 8bfdc87689..e93e993776 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -51,6 +51,7 @@ enum { IFLA_VRF_UNSPEC, IFLA_VRF_TABLE, __IFLA_VRF_MAX };
*/
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF name\n"
#define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n"
+#define VRF_FULL_CMD_HELP_STR "Specify the VRF\nThe VRF name\nAll VRFs\n"
/*
* Pass some OS specific data up through
diff --git a/lib/vty.c b/lib/vty.c
index 12c3c12394..4026e0cf8a 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -2279,6 +2279,21 @@ static void vty_read_file(FILE *confp)
case CMD_ERR_NO_MATCH:
message = "No such command";
break;
+ case CMD_WARNING:
+ message = "Command returned Warning";
+ break;
+ case CMD_WARNING_CONFIG_FAILED:
+ message = "Command returned Warning Config Failed";
+ break;
+ case CMD_ERR_INCOMPLETE:
+ message = "Command returned Incomplete";
+ break;
+ case CMD_ERR_EXEED_ARGC_MAX:
+ message = "Command exceeded maximum number of Arguments";
+ break;
+ default:
+ message = "Command returned unhandled error message";
+ break;
}
nl = strchr(vty->error_buf, '\n');
diff --git a/lib/zclient.c b/lib/zclient.c
index d23e5fbd79..8ada2cf978 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -574,7 +574,6 @@ void zclient_init(struct zclient *zclient, int redist_default,
/* Set default-information redistribute to zero. */
zclient->default_information = vrf_bitmap_init();
- ;
if (zclient_debug)
zlog_debug("zclient_start is called");
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index a9239c2835..10b68ab735 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -4252,11 +4252,16 @@ DEFUN (show_ip_pim_nexthop_lookup,
memset(&nexthop, 0, sizeof(nexthop));
if (pim_find_or_track_nexthop(vrf->info, &nht_p, NULL, NULL, &pnc))
- pim_ecmp_nexthop_search(vrf->info, &pnc, &nexthop, &nht_p, &grp,
- 0);
+ result = pim_ecmp_nexthop_search(vrf->info, &pnc, &nexthop,
+ &nht_p, &grp, 0);
else
- pim_ecmp_nexthop_lookup(vrf->info, &nexthop, vif_source, &nht_p,
- &grp, 0);
+ result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, vif_source,
+ &nht_p, &grp, 0);
+
+ if (!result) {
+ vty_out(vty, "Nexthop Lookup failed, no usable routes returned.\n");
+ return CMD_SUCCESS;
+ }
pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 5dc64a1b3f..b2a8a6ff8f 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -797,7 +797,11 @@ void pim_if_addr_del_all(struct interface *ifp)
struct listnode *node;
struct listnode *nextnode;
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
- struct pim_instance *pim = vrf->info;
+ struct pim_instance *pim;
+
+ if (!vrf)
+ return;
+ pim = vrf->info;
/* PIM/IGMP enabled ? */
if (!ifp->info)
@@ -860,12 +864,15 @@ struct in_addr pim_find_primary_addr(struct interface *ifp)
{
struct connected *ifc;
struct listnode *node;
- struct in_addr addr;
+ struct in_addr addr = {0};
int v4_addrs = 0;
int v6_addrs = 0;
struct pim_interface *pim_ifp = ifp->info;
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
+ if (!vrf)
+ return addr;
+
if (pim_ifp && PIM_INADDR_ISNOT_ANY(pim_ifp->update_source)) {
return pim_ifp->update_source;
}
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 8f9058d994..e2984e1d13 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -648,7 +648,11 @@ int pim_parse_nexthop_update(int command, struct zclient *zclient,
struct interface *ifp = NULL;
struct interface *ifp1 = NULL;
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
- struct pim_instance *pim = vrf->info;
+ struct pim_instance *pim;
+
+ if (!vrf)
+ return 0;
+ pim = vrf->info;
s = zclient->ibuf;
memset(&p, 0, sizeof(struct prefix));
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 8c90ccbed1..04466258bb 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -348,7 +348,11 @@ static int pim_zebra_if_address_del(int command, struct zclient *client,
struct connected *c;
struct prefix *p;
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
- struct pim_instance *pim = vrf->info;
+ struct pim_instance *pim;
+
+ if (!vrf)
+ return 0;
+ pim = vrf->info;
/*
zebra api notifies address adds/dels events by using the same call
@@ -595,7 +599,9 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
zlog_debug(
"%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
__FILE__, __PRETTY_FUNCTION__, source_str, group_str,
- old_iif->name, c_oil->oil.mfcc_parent, new_iif->name,
+ (old_iif) ? old_iif->name : "<old_iif?>",
+ c_oil->oil.mfcc_parent,
+ (new_iif) ? new_iif->name : "<new_iif?>",
input_iface_vif_index);
}
@@ -614,7 +620,8 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
zlog_debug(
"%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
__FILE__, __PRETTY_FUNCTION__, source_str,
- group_str, new_iif->name,
+ group_str,
+ (new_iif) ? new_iif->name : "<new_iif?>",
input_iface_vif_index);
}
}
diff --git a/python/clidef.py b/python/clidef.py
index 6a69986323..fe01a89162 100644
--- a/python/clidef.py
+++ b/python/clidef.py
@@ -188,8 +188,6 @@ def process_file(fn, ofd, dumpfd, all_defun):
for entry in filedata['data']:
if entry['type'] == 'DEFPY' or (all_defun and entry['type'].startswith('DEFUN')):
cmddef = entry['args'][2]
- for i in cmddef:
- assert i.startswith('"') and i.endswith('"')
cmddef = ''.join([i[1:-1] for i in cmddef])
graph = clippy.Graph(cmddef)
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index a2235904c6..cf8bdf5a8e 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -31,6 +31,7 @@
#define _LINUX_IN6_H
#include <linux/if_bridge.h>
+#include <linux/if_link.h>
#include <net/if_arp.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
@@ -255,47 +256,6 @@ static void netlink_determine_zebra_iftype(char *kind, zebra_iftype_t *zif_type)
*zif_type = ZEBRA_IF_MACVLAN;
}
-// Temporary Assignments to compile on older platforms.
-#ifndef IFLA_BR_MAX
-#define IFLA_BR_MAX 39
-#endif
-
-#ifndef IFLA_VXLAN_ID
-#define IFLA_VXLAN_ID 1
-#endif
-
-#ifndef IFLA_VXLAN_LOCAL
-#define IFLA_VXLAN_LOCAL 4
-#endif
-
-#ifndef IFLA_VXLAN_MAX
-#define IFLA_VXLAN_MAX 26
-#endif
-
-#ifndef IFLA_BRIDGE_MAX
-#define IFLA_BRIDGE_MAX 2
-#endif
-
-#ifndef IFLA_BRIDGE_VLAN_INFO
-#define IFLA_BRIDGE_VLAN_INFO 2
-#endif
-
-#ifndef BRIDGE_VLAN_INFO_PVID
-#define BRIDGE_VLAN_INFO_PVID (1<<1)
-#endif
-
-#ifndef RTEXT_FILTER_BRVLAN
-#define RTEXT_FILTER_BRVLAN (1<<1)
-#endif
-
-#ifndef NTF_SELF
-#define NTF_SELF 0x02
-#endif
-
-#ifndef IFLA_BR_VLAN_FILTERING
-#define IFLA_BR_VLAN_FILTERING 7
-#endif
-
#define parse_rtattr_nested(tb, max, rta) \
netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 0cc2e0217f..e8333ef0cf 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -23,6 +23,10 @@
#ifdef HAVE_NETLINK
#include <net/if_arp.h>
+#include <linux/lwtunnel.h>
+#include <linux/mpls_iptunnel.h>
+#include <linux/neighbour.h>
+#include <linux/rtnetlink.h>
/* Hack for GNU libc version 2. */
#ifndef MSG_TRUNC
@@ -61,65 +65,10 @@
#include "zebra/zebra_mroute.h"
#include "zebra/zebra_vxlan.h"
-
-/* TODO - Temporary definitions, need to refine. */
#ifndef AF_MPLS
#define AF_MPLS 28
#endif
-#ifndef RTA_VIA
-#define RTA_VIA 18
-#endif
-
-#ifndef RTA_NEWDST
-#define RTA_NEWDST 19
-#endif
-
-#ifndef RTA_ENCAP_TYPE
-#define RTA_ENCAP_TYPE 21
-#endif
-
-#ifndef RTA_ENCAP
-#define RTA_ENCAP 22
-#endif
-
-#ifndef RTA_EXPIRES
-#define RTA_EXPIRES 23
-#endif
-
-#ifndef LWTUNNEL_ENCAP_MPLS
-#define LWTUNNEL_ENCAP_MPLS 1
-#endif
-
-#ifndef MPLS_IPTUNNEL_DST
-#define MPLS_IPTUNNEL_DST 1
-#endif
-
-#ifndef NDA_MASTER
-#define NDA_MASTER 9
-#endif
-
-#ifndef NTF_MASTER
-#define NTF_MASTER 0x04
-#endif
-
-#ifndef NTF_SELF
-#define NTF_SELF 0x02
-#endif
-
-#ifndef NTF_EXT_LEARNED
-#define NTF_EXT_LEARNED 0x10
-#endif
-
-#ifndef NDA_IFINDEX
-#define NDA_IFINDEX 8
-#endif
-
-#ifndef NDA_VLAN
-#define NDA_VLAN 5
-#endif
-/* End of temporary definitions */
-
static vlanid_t filter_vlan = 0;
struct gw_family_t {
@@ -2370,7 +2319,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE);
-
/*
* Count # nexthops so we can decide whether to use singlepath
* or multipath case.
@@ -2394,11 +2342,9 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
}
}
- if (nexthop_num == 0 || !lsp->best_nhlfe) // unexpected
+ if ((nexthop_num == 0) || (!lsp->best_nhlfe && (cmd != RTM_DELROUTE)))
return 0;
- route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
-
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
req.n.nlmsg_type = cmd;
@@ -2407,14 +2353,18 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
req.r.rtm_family = AF_MPLS;
req.r.rtm_table = RT_TABLE_MAIN;
req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
- req.r.rtm_protocol = zebra2proto(route_type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
req.r.rtm_type = RTN_UNICAST;
- if (cmd == RTM_NEWROUTE)
+ if (cmd == RTM_NEWROUTE) {
/* We do a replace to handle update. */
req.n.nlmsg_flags |= NLM_F_REPLACE;
+ /* set the protocol value if installing */
+ route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
+ req.r.rtm_protocol = zebra2proto(route_type);
+ }
+
/* Fill destination */
lse = mpls_lse_encode(lsp->ile.in_label, 0, 0, 1);
addattr_l(&req.n, sizeof req, RTA_DST, &lse, sizeof(mpls_lse_t));
@@ -2524,23 +2474,4 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
0);
}
-
-/*
- * Handle failure in LSP install, clear flags for NHLFE.
- */
-void clear_nhlfe_installed(zebra_lsp_t *lsp)
-{
- zebra_nhlfe_t *nhlfe;
- struct nexthop *nexthop;
-
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
- nexthop = nhlfe->nexthop;
- if (!nexthop)
- continue;
-
- UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
- UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
- }
-}
-
#endif /* HAVE_NETLINK */
diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h
index 980ff915cc..afb03f878d 100644
--- a/zebra/rt_netlink.h
+++ b/zebra/rt_netlink.h
@@ -54,7 +54,6 @@
void rt_netlink_init(void);
-extern void clear_nhlfe_installed(zebra_lsp_t *lsp);
extern int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp);
extern int netlink_route_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 7b87355ed4..3765849adf 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -130,6 +130,24 @@ static int mpls_processq_init(struct zebra_t *zebra);
/* Static functions */
/*
+ * Handle failure in LSP install, clear flags for NHLFE.
+ */
+static void clear_nhlfe_installed(zebra_lsp_t *lsp)
+{
+ zebra_nhlfe_t *nhlfe;
+ struct nexthop *nexthop;
+
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
+ nexthop = nhlfe->nexthop;
+ if (!nexthop)
+ continue;
+
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+ }
+}
+
+/*
* Install label forwarding entry based on labeled-route entry.
*/
static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
@@ -821,11 +839,16 @@ static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)
*/
static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt)
{
+ int ret;
zebra_lsp_t *lsp;
lsp = (zebra_lsp_t *)backet->data;
- if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
- kernel_del_lsp(lsp);
+ if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
+ ret = kernel_del_lsp(lsp);
+
+ if (!ret)
+ clear_nhlfe_installed(lsp);
+ }
}
/*
@@ -846,6 +869,7 @@ static void lsp_schedule(struct hash_backet *backet, void *ctxt)
*/
static wq_item_status lsp_process(struct work_queue *wq, void *data)
{
+ int ret = 1;
zebra_lsp_t *lsp;
zebra_nhlfe_t *oldbest, *newbest;
char buf[BUFSIZ], buf2[BUFSIZ];
@@ -877,20 +901,23 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
/* Not already installed */
if (newbest) {
- kernel_add_lsp(lsp);
+ ret = kernel_add_lsp(lsp);
zvrf->lsp_installs++;
}
} else {
/* Installed, may need an update and/or delete. */
if (!newbest) {
- kernel_del_lsp(lsp);
+ ret = kernel_del_lsp(lsp);
zvrf->lsp_removals++;
} else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) {
- kernel_upd_lsp(lsp);
+ ret = kernel_upd_lsp(lsp);
zvrf->lsp_installs++;
}
}
+ if (!ret)
+ clear_nhlfe_installed(lsp);
+
return WQ_SUCCESS;
}
diff --git a/zebra/zebra_mpls_netlink.c b/zebra/zebra_mpls_netlink.c
index 8b30783a9a..887c685498 100644
--- a/zebra/zebra_mpls_netlink.c
+++ b/zebra/zebra_mpls_netlink.c
@@ -40,8 +40,6 @@ int kernel_add_lsp(zebra_lsp_t *lsp)
ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp);
if (!ret)
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
- else
- clear_nhlfe_installed(lsp);
return ret;
}
@@ -60,22 +58,32 @@ int kernel_add_lsp(zebra_lsp_t *lsp)
int kernel_upd_lsp(zebra_lsp_t *lsp)
{
int ret;
+ zebra_nhlfe_t *nhlfe;
+ struct nexthop *nexthop;
if (!lsp || !lsp->best_nhlfe) // unexpected
return -1;
UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED);
- /* First issue a DEL and clear the installed flag. */
- netlink_mpls_multipath(RTM_DELROUTE, lsp);
- UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
+ /* Any NHLFE that was installed but is not selected now needs to
+ * have its flags updated.
+ */
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
+ nexthop = nhlfe->nexthop;
+ if (!nexthop)
+ continue;
+
+ if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) &&
+ !CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)) {
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+ }
+ }
- /* Then issue an ADD. */
ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp);
if (!ret)
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
- else
- clear_nhlfe_installed(lsp);
return ret;
}
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index e6563c4f54..73f0717124 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -50,11 +50,16 @@ extern int allow_delete;
static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
safi_t safi, bool use_fib, u_char use_json,
- route_tag_t tag, struct prefix *longer_prefix_p,
+ route_tag_t tag,
+ const struct prefix *longer_prefix_p,
bool supernets_only, int type,
u_short ospf_instance_id);
static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
int mcast);
+static void vty_show_ip_route_summary(struct vty *vty,
+ struct route_table *table);
+static void vty_show_ip_route_summary_prefix(struct vty *vty,
+ struct route_table *table);
/* VNI range as per RFC 7432 */
#define CMD_VNI_RANGE "(1-16777215)"
@@ -936,14 +941,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
}
}
-static bool use_fib(struct cmd_token *token)
-{
- return strncmp(token->arg, "route", strlen(token->arg));
-}
-
static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
safi_t safi, bool use_fib, u_char use_json,
- route_tag_t tag, struct prefix *longer_prefix_p,
+ route_tag_t tag,
+ const struct prefix *longer_prefix_p,
bool supernets_only, int type,
u_short ospf_instance_id)
{
@@ -1201,14 +1202,33 @@ DEFUN (no_ipv6_nht_default_route,
return CMD_SUCCESS;
}
-DEFUN (show_ip_route,
- show_ip_route_cmd,
- "show ip <fib|route> [vrf NAME] [tag (1-4294967295)|A.B.C.D/M longer-prefixes|supernets-only|" FRR_IP_REDIST_STR_ZEBRA "|ospf (1-65535)] [json]",
+DEFPY (show_route,
+ show_route_cmd,
+ "show\
+ <\
+ ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
+ [{\
+ tag (1-4294967295)\
+ |A.B.C.D/M$prefix longer-prefixes\
+ |supernets-only$supernets_only\
+ }]\
+ [<\
+ " FRR_IP_REDIST_STR_ZEBRA "$type_str\
+ |ospf$type_str (1-65535)$ospf_instance_id\
+ >]\
+ |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
+ [{\
+ tag (1-4294967295)\
+ |X:X::X:X/M$prefix longer-prefixes\
+ }]\
+ [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
+ >\
+ [json$json]",
SHOW_STR
IP_STR
"IP forwarding table\n"
"IP routing table\n"
- VRF_CMD_HELP_STR
+ VRF_FULL_CMD_HELP_STR
"Show only routes with tag\n"
"Tag value\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
@@ -1217,75 +1237,23 @@ DEFUN (show_ip_route,
FRR_IP_REDIST_HELP_STR_ZEBRA
"Open Shortest Path First (OSPFv2)\n"
"Instance ID\n"
+ IPV6_STR
+ "IP forwarding table\n"
+ "IP routing table\n"
+ VRF_FULL_CMD_HELP_STR
+ "Show only routes with tag\n"
+ "Tag value\n"
+ "IPv6 prefix\n"
+ "Show route matching the specified Network/Mask pair only\n"
+ FRR_IP6_REDIST_HELP_STR_ZEBRA
JSON_STR)
{
- bool uf = use_fib(argv[2]);
- struct route_table *table;
- int vrf_all = 0;
- route_tag_t tag = 0;
- vrf_id_t vrf_id = VRF_DEFAULT;
+ afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
struct vrf *vrf;
- struct zebra_vrf *zvrf;
- int uj = use_json(argc, argv);
- int idx = 0;
- struct prefix p;
- bool longer_prefixes = false;
- bool supernets_only = false;
int type = 0;
- u_short ospf_instance_id = 0;
-
- if (argv_find(argv, argc, "vrf", &idx)) {
- if (strmatch(argv[idx + 1]->arg, "all"))
- vrf_all = 1;
- else
- VRF_GET_ID(vrf_id, argv[idx + 1]->arg);
- }
-
- if (argv_find(argv, argc, "tag", &idx))
- tag = strtoul(argv[idx + 1]->arg, NULL, 10);
-
- else if (argv_find(argv, argc, "A.B.C.D/M", &idx)) {
- if (str2prefix(argv[idx]->arg, &p) <= 0) {
- vty_out(vty, "%% Malformed prefix\n");
- return CMD_WARNING;
- }
- longer_prefixes = true;
- }
-
- else if (argv_find(argv, argc, "supernets_only", &idx))
- supernets_only = true;
-
- else {
- if (argv_find(argv, argc, "kernel", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "babel", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "connected", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "static", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "rip", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "ospf", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "isis", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "bgp", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "pim", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "eigrp", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "nhrp", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "table", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
- else if (argv_find(argv, argc, "vnc", &idx))
- type = proto_redistnum(AFI_IP, argv[idx]->text);
-
- if (argv_find(argv, argc, "(1-65535)", &idx))
- ospf_instance_id = strtoul(argv[idx]->arg, NULL, 10);
+ if (type_str) {
+ type = proto_redistnum(afi, type_str);
if (type < 0) {
vty_out(vty, "Unknown route type\n");
return CMD_WARNING;
@@ -1294,114 +1262,178 @@ DEFUN (show_ip_route,
if (vrf_all) {
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ struct zebra_vrf *zvrf;
+ struct route_table *table;
+
if ((zvrf = vrf->info) == NULL
- || (table = zvrf->table[AFI_IP][SAFI_UNICAST])
- == NULL)
+ || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
continue;
do_show_ip_route(
- vty, zvrf_name(zvrf), AFI_IP, SAFI_UNICAST, uf,
- uj, tag, longer_prefixes ? &p : NULL,
- supernets_only, type, ospf_instance_id);
+ vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
+ !!json, tag, prefix_str ? prefix : NULL,
+ !!supernets_only, type, ospf_instance_id);
}
} else {
+ vrf_id_t vrf_id = VRF_DEFAULT;
+
+ if (vrf_name)
+ VRF_GET_ID(vrf_id, vrf_name);
vrf = vrf_lookup_by_id(vrf_id);
- do_show_ip_route(vty, vrf->name, AFI_IP, SAFI_UNICAST, uf, uj,
- tag, longer_prefixes ? &p : NULL,
- supernets_only, type, ospf_instance_id);
+ do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
+ !!json, tag, prefix_str ? prefix : NULL,
+ !!supernets_only, type, ospf_instance_id);
}
+
return CMD_SUCCESS;
}
-DEFUN (show_ip_route_addr,
- show_ip_route_addr_cmd,
- "show ip route [vrf NAME] A.B.C.D",
+DEFPY (show_route_detail,
+ show_route_detail_cmd,
+ "show\
+ <\
+ ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
+ <\
+ A.B.C.D$address\
+ |A.B.C.D/M$prefix\
+ >\
+ |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
+ <\
+ X:X::X:X$address\
+ |X:X::X:X/M$prefix\
+ >\
+ >",
SHOW_STR
IP_STR
"IP routing table\n"
- VRF_CMD_HELP_STR
- "Network in the IP routing table to display\n")
+ VRF_FULL_CMD_HELP_STR
+ "Network in the IP routing table to display\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ IP6_STR
+ "IP routing table\n"
+ VRF_FULL_CMD_HELP_STR
+ "IPv6 Address\n"
+ "IPv6 prefix\n")
{
- int ret;
- struct prefix_ipv4 p;
+ afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
struct route_table *table;
+ struct prefix p;
struct route_node *rn;
- vrf_id_t vrf_id = VRF_DEFAULT;
- if (strmatch(argv[3]->text, "vrf")) {
- VRF_GET_ID(vrf_id, argv[4]->arg);
- ret = str2prefix_ipv4(argv[5]->arg, &p);
- } else {
- ret = str2prefix_ipv4(argv[3]->arg, &p);
- }
-
- if (ret <= 0) {
- vty_out(vty, "%% Malformed IPv4 address\n");
+ if (address_str)
+ prefix_str = address_str;
+ if (str2prefix(prefix_str, &p) < 0) {
+ vty_out(vty, "%% Malformed address\n");
return CMD_WARNING;
}
- table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
+ if (vrf_all) {
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn) {
- vty_out(vty, "%% Network not in table\n");
- return CMD_WARNING;
- }
+ RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
+ if ((zvrf = vrf->info) == NULL
+ || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
+ continue;
+
+ rn = route_node_match(table, &p);
+ if (!rn)
+ continue;
+ if (!address_str && rn->p.prefixlen != p.prefixlen) {
+ route_unlock_node(rn);
+ continue;
+ }
+
+ vty_show_ip_route_detail(vty, rn, 0);
+
+ route_unlock_node(rn);
+ }
+ } else {
+ vrf_id_t vrf_id = VRF_DEFAULT;
+
+ if (vrf_name)
+ VRF_GET_ID(vrf_id, vrf_name);
+
+ table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
+ if (!table)
+ return CMD_SUCCESS;
+
+ rn = route_node_match(table, &p);
+ if (!rn) {
+ vty_out(vty, "%% Network not in table\n");
+ return CMD_WARNING;
+ }
+ if (!address_str && rn->p.prefixlen != p.prefixlen) {
+ vty_out(vty, "%% Network not in table\n");
+ route_unlock_node(rn);
+ return CMD_WARNING;
+ }
- vty_show_ip_route_detail(vty, rn, 0);
+ vty_show_ip_route_detail(vty, rn, 0);
- route_unlock_node(rn);
+ route_unlock_node(rn);
+ }
return CMD_SUCCESS;
}
-DEFUN (show_ip_route_prefix,
- show_ip_route_prefix_cmd,
- "show ip route [vrf NAME] A.B.C.D/M",
+DEFPY (show_route_summary,
+ show_route_summary_cmd,
+ "show\
+ <\
+ ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
+ summary [prefix$prefix]\
+ |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
+ summary [prefix$prefix]\
+ >",
SHOW_STR
IP_STR
"IP routing table\n"
- VRF_CMD_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+ VRF_FULL_CMD_HELP_STR
+ "Summary of all routes\n"
+ "Prefix routes\n"
+ IP6_STR
+ "IP routing table\n"
+ VRF_FULL_CMD_HELP_STR
+ "Summary of all routes\n"
+ "Prefix routes\n")
{
- int ret;
- struct prefix_ipv4 p;
+ afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
struct route_table *table;
- struct route_node *rn;
- vrf_id_t vrf_id = VRF_DEFAULT;
- if (strmatch(argv[3]->text, "vrf")) {
- VRF_GET_ID(vrf_id, argv[4]->arg);
- ret = str2prefix_ipv4(argv[5]->arg, &p);
- } else {
- ret = str2prefix_ipv4(argv[3]->arg, &p);
- }
+ if (vrf_all) {
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
- if (ret <= 0) {
- vty_out(vty, "%% Malformed IPv4 address\n");
- return CMD_WARNING;
- }
+ RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
+ if ((zvrf = vrf->info) == NULL
+ || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
+ continue;
- table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
+ if (prefix)
+ vty_show_ip_route_summary_prefix(vty, table);
+ else
+ vty_show_ip_route_summary(vty, table);
+ }
+ } else {
+ vrf_id_t vrf_id = VRF_DEFAULT;
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn || rn->p.prefixlen != p.prefixlen) {
- vty_out(vty, "%% Network not in table\n");
- return CMD_WARNING;
- }
+ if (vrf_name)
+ VRF_GET_ID(vrf_id, vrf_name);
- vty_show_ip_route_detail(vty, rn, 0);
+ table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
+ if (!table)
+ return CMD_SUCCESS;
- route_unlock_node(rn);
+ if (prefix)
+ vty_show_ip_route_summary_prefix(vty, table);
+ else
+ vty_show_ip_route_summary(vty, table);
+ }
return CMD_SUCCESS;
}
-
static void vty_show_ip_route_summary(struct vty *vty,
struct route_table *table)
{
@@ -1540,183 +1572,6 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
vty_out(vty, "\n");
}
-/* Show route summary. */
-DEFUN (show_ip_route_summary,
- show_ip_route_summary_cmd,
- "show ip route [vrf NAME] summary",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all routes\n")
-{
- struct route_table *table;
- vrf_id_t vrf_id = VRF_DEFAULT;
-
- if (strmatch(argv[3]->text, "vrf"))
- VRF_GET_ID(vrf_id, argv[4]->arg);
-
- table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
-
- vty_show_ip_route_summary(vty, table);
-
- return CMD_SUCCESS;
-}
-
-/* Show route summary prefix. */
-DEFUN (show_ip_route_summary_prefix,
- show_ip_route_summary_prefix_cmd,
- "show ip route [vrf NAME] summary prefix",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all routes\n"
- "Prefix routes\n")
-{
- struct route_table *table;
- vrf_id_t vrf_id = VRF_DEFAULT;
-
- if (strmatch(argv[3]->text, "vrf"))
- VRF_GET_ID(vrf_id, argv[4]->arg);
-
- table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
-
- vty_show_ip_route_summary_prefix(vty, table);
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (show_ip_route_vrf_all_addr,
- show_ip_route_vrf_all_addr_cmd,
- "show ip route vrf all A.B.C.D",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_ALL_CMD_HELP_STR
- "Network in the IP routing table to display\n")
-{
- int idx_ipv4 = 5;
- int ret;
- struct prefix_ipv4 p;
- struct route_table *table;
- struct route_node *rn;
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed IPv4 address\n");
- return CMD_WARNING;
- }
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if ((zvrf = vrf->info) == NULL
- || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
- continue;
-
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn)
- continue;
-
- vty_show_ip_route_detail(vty, rn, 0);
-
- route_unlock_node(rn);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_route_vrf_all_prefix,
- show_ip_route_vrf_all_prefix_cmd,
- "show ip route vrf all A.B.C.D/M",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_ALL_CMD_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-{
- int idx_ipv4_prefixlen = 5;
- int ret;
- struct prefix_ipv4 p;
- struct route_table *table;
- struct route_node *rn;
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed IPv4 address\n");
- return CMD_WARNING;
- }
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if ((zvrf = vrf->info) == NULL
- || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
- continue;
-
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn)
- continue;
- if (rn->p.prefixlen != p.prefixlen) {
- route_unlock_node(rn);
- continue;
- }
-
- vty_show_ip_route_detail(vty, rn, 0);
-
- route_unlock_node(rn);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_route_vrf_all_summary,
- show_ip_route_vrf_all_summary_cmd,
- "show ip route vrf all summary ",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_ALL_CMD_HELP_STR
- "Summary of all routes\n")
-{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
- if ((zvrf = vrf->info) != NULL)
- vty_show_ip_route_summary(
- vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_route_vrf_all_summary_prefix,
- show_ip_route_vrf_all_summary_prefix_cmd,
- "show ip route vrf all summary prefix",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_ALL_CMD_HELP_STR
- "Summary of all routes\n"
- "Prefix routes\n")
-{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
- if ((zvrf = vrf->info) != NULL)
- vty_show_ip_route_summary_prefix(
- vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
-
- return CMD_SUCCESS;
-}
-
/* Write static route configuration. */
static int static_config(struct vty *vty, afi_t afi, safi_t safi,
const char *cmd)
@@ -1901,245 +1756,6 @@ DEFPY(ipv6_route,
tag_str, distance_str, vrf, label);
}
-DEFUN (show_ipv6_route,
- show_ipv6_route_cmd,
- "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA "] [json]",
- SHOW_STR
- IP_STR
- "IP forwarding table\n"
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Show only routes with tag\n"
- "Tag value\n"
- "IPv6 prefix\n"
- "Show route matching the specified Network/Mask pair only\n"
- FRR_IP6_REDIST_HELP_STR_ZEBRA
- JSON_STR)
-{
- bool uf = use_fib(argv[2]);
- struct route_table *table;
- int vrf_all = 0;
- route_tag_t tag = 0;
- vrf_id_t vrf_id = VRF_DEFAULT;
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
- int uj = use_json(argc, argv);
- int idx = 0;
- struct prefix p;
- bool longer_prefixes = false;
- bool supernets_only = false;
- int type = 0;
-
- if (argv_find(argv, argc, "vrf", &idx)) {
- if (strmatch(argv[idx + 1]->arg, "all"))
- vrf_all = 1;
- else
- VRF_GET_ID(vrf_id, argv[idx + 1]->arg);
- }
-
- if (argv_find(argv, argc, "tag", &idx))
- tag = strtoul(argv[idx + 1]->arg, NULL, 10);
-
- else if (argv_find(argv, argc, "X:X::X:X/M", &idx)) {
- if (str2prefix(argv[idx]->arg, &p) <= 0) {
- vty_out(vty, "%% Malformed prefix\n");
- return CMD_WARNING;
- }
- longer_prefixes = true;
- }
-
- else {
- if (argv_find(argv, argc, "kernel", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "babel", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "connected", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "static", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "ripng", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "ospf6", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "isis", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "bgp", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "nhrp", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "table", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
- else if (argv_find(argv, argc, "vnc", &idx))
- type = proto_redistnum(AFI_IP6, argv[idx]->text);
-
- if (type < 0) {
- vty_out(vty, "Unknown route type\n");
- return CMD_WARNING;
- }
- }
-
- if (vrf_all) {
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if ((zvrf = vrf->info) == NULL
- || (table = zvrf->table[AFI_IP6][SAFI_UNICAST])
- == NULL)
- continue;
-
- do_show_ip_route(vty, zvrf_name(zvrf), AFI_IP6,
- SAFI_UNICAST, uf, uj, tag,
- longer_prefixes ? &p : NULL,
- supernets_only, type, 0);
- }
- } else {
- vrf = vrf_lookup_by_id(vrf_id);
- do_show_ip_route(vty, vrf->name, AFI_IP6, SAFI_UNICAST, uf, uj,
- tag, longer_prefixes ? &p : NULL,
- supernets_only, type, 0);
- }
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ipv6_route_addr,
- show_ipv6_route_addr_cmd,
- "show ipv6 route [vrf NAME] X:X::X:X",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "IPv6 Address\n")
-{
- int ret;
- struct prefix_ipv6 p;
- struct route_table *table;
- struct route_node *rn;
- vrf_id_t vrf_id = VRF_DEFAULT;
-
- if (strmatch(argv[3]->text, "vrf")) {
- VRF_GET_ID(vrf_id, argv[4]->arg);
- ret = str2prefix_ipv6(argv[5]->arg, &p);
- } else {
- ret = str2prefix_ipv6(argv[3]->arg, &p);
- }
-
- if (ret <= 0) {
- vty_out(vty, "Malformed IPv6 address\n");
- return CMD_WARNING;
- }
-
- table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
-
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn) {
- vty_out(vty, "%% Network not in table\n");
- return CMD_WARNING;
- }
-
- vty_show_ip_route_detail(vty, rn, 0);
-
- route_unlock_node(rn);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ipv6_route_prefix,
- show_ipv6_route_prefix_cmd,
- "show ipv6 route [vrf NAME] X:X::X:X/M",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "IPv6 prefix\n")
-{
- int ret;
- struct prefix_ipv6 p;
- struct route_table *table;
- struct route_node *rn;
- vrf_id_t vrf_id = VRF_DEFAULT;
-
- if (strmatch(argv[3]->text, "vrf")) {
- VRF_GET_ID(vrf_id, argv[4]->arg);
- ret = str2prefix_ipv6(argv[5]->arg, &p);
- } else
- ret = str2prefix_ipv6(argv[3]->arg, &p);
-
- if (ret <= 0) {
- vty_out(vty, "Malformed IPv6 prefix\n");
- return CMD_WARNING;
- }
-
- table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
-
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn || rn->p.prefixlen != p.prefixlen) {
- vty_out(vty, "%% Network not in table\n");
- return CMD_WARNING;
- }
-
- vty_show_ip_route_detail(vty, rn, 0);
-
- route_unlock_node(rn);
-
- return CMD_SUCCESS;
-}
-
-
-/* Show route summary. */
-DEFUN (show_ipv6_route_summary,
- show_ipv6_route_summary_cmd,
- "show ipv6 route [vrf NAME] summary",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all IPv6 routes\n")
-{
- struct route_table *table;
- vrf_id_t vrf_id = VRF_DEFAULT;
-
- if (strmatch(argv[3]->text, "vrf"))
- VRF_GET_ID(vrf_id, argv[4]->arg);
-
- table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
-
- vty_show_ip_route_summary(vty, table);
-
- return CMD_SUCCESS;
-}
-
-
-/* Show ipv6 route summary prefix. */
-DEFUN (show_ipv6_route_summary_prefix,
- show_ipv6_route_summary_prefix_cmd,
- "show ipv6 route [vrf NAME] summary prefix",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all IPv6 routes\n"
- "Prefix routes\n")
-{
- struct route_table *table;
- vrf_id_t vrf_id = VRF_DEFAULT;
-
- if (strmatch(argv[3]->text, "vrf"))
- VRF_GET_ID(vrf_id, argv[4]->arg);
-
- table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
- if (!table)
- return CMD_SUCCESS;
-
- vty_show_ip_route_summary_prefix(vty, table);
-
- return CMD_SUCCESS;
-}
-
-
/*
* Show IPv6 mroute command.Used to dump
* the Multicast routing table.
@@ -2177,110 +1793,6 @@ DEFUN (show_ipv6_mroute,
return CMD_SUCCESS;
}
-DEFUN (show_ipv6_route_vrf_all_addr,
- show_ipv6_route_vrf_all_addr_cmd,
- "show ipv6 route vrf all X:X::X:X",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_ALL_CMD_HELP_STR
- "IPv6 Address\n")
-{
- int idx_ipv6 = 5;
- int ret;
- struct prefix_ipv6 p;
- struct route_table *table;
- struct route_node *rn;
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- ret = str2prefix_ipv6(argv[idx_ipv6]->arg, &p);
- if (ret <= 0) {
- vty_out(vty, "Malformed IPv6 address\n");
- return CMD_WARNING;
- }
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if ((zvrf = vrf->info) == NULL
- || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
- continue;
-
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn)
- continue;
-
- vty_show_ip_route_detail(vty, rn, 0);
-
- route_unlock_node(rn);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ipv6_route_vrf_all_prefix,
- show_ipv6_route_vrf_all_prefix_cmd,
- "show ipv6 route vrf all X:X::X:X/M",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_ALL_CMD_HELP_STR
- "IPv6 prefix\n")
-{
- int idx_ipv6_prefixlen = 5;
- int ret;
- struct prefix_ipv6 p;
- struct route_table *table;
- struct route_node *rn;
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg, &p);
- if (ret <= 0) {
- vty_out(vty, "Malformed IPv6 prefix\n");
- return CMD_WARNING;
- }
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if ((zvrf = vrf->info) == NULL
- || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
- continue;
-
- rn = route_node_match(table, (struct prefix *)&p);
- if (!rn)
- continue;
- if (rn->p.prefixlen != p.prefixlen) {
- route_unlock_node(rn);
- continue;
- }
-
- vty_show_ip_route_detail(vty, rn, 0);
-
- route_unlock_node(rn);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ipv6_route_vrf_all_summary,
- show_ipv6_route_vrf_all_summary_cmd,
- "show ipv6 route vrf all summary",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_ALL_CMD_HELP_STR
- "Summary of all IPv6 routes\n")
-{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
- if ((zvrf = vrf->info) != NULL)
- vty_show_ip_route_summary(
- vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
-
- return CMD_SUCCESS;
-}
-
DEFUN (show_ipv6_mroute_vrf_all,
show_ipv6_mroute_vrf_all_cmd,
"show ipv6 mroute vrf all",
@@ -2314,27 +1826,6 @@ DEFUN (show_ipv6_mroute_vrf_all,
return CMD_SUCCESS;
}
-DEFUN (show_ipv6_route_vrf_all_summary_prefix,
- show_ipv6_route_vrf_all_summary_prefix_cmd,
- "show ipv6 route vrf all summary prefix",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_ALL_CMD_HELP_STR
- "Summary of all IPv6 routes\n"
- "Prefix routes\n")
-{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
- if ((zvrf = vrf->info) != NULL)
- vty_show_ip_route_summary_prefix(
- vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
-
- return CMD_SUCCESS;
-}
-
DEFUN (allow_external_route_update,
allow_external_route_update_cmd,
"allow-external-route-update",
@@ -2848,24 +2339,17 @@ void zebra_vty_init(void)
install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
install_element(VIEW_NODE, &show_vrf_cmd);
- install_element(VIEW_NODE, &show_ip_route_cmd);
+ install_element(VIEW_NODE, &show_route_cmd);
+ install_element(VIEW_NODE, &show_route_detail_cmd);
+ install_element(VIEW_NODE, &show_route_summary_cmd);
install_element(VIEW_NODE, &show_ip_nht_cmd);
install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
install_element(VIEW_NODE, &show_ipv6_nht_cmd);
install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
- install_element(VIEW_NODE, &show_ip_route_addr_cmd);
- install_element(VIEW_NODE, &show_ip_route_prefix_cmd);
- install_element(VIEW_NODE, &show_ip_route_summary_cmd);
- install_element(VIEW_NODE, &show_ip_route_summary_prefix_cmd);
install_element(VIEW_NODE, &show_ip_rpf_cmd);
install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
- install_element(VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
- install_element(VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
- install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
- install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
-
install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
install_element(CONFIG_NODE, &ipv6_route_cmd);
@@ -2873,19 +2357,9 @@ void zebra_vty_init(void)
install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_summary_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_addr_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_prefix_cmd);
install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
/* Commands for VRF */
- install_element(VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
- install_element(VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
-
install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
install_element(VIEW_NODE, &show_evpn_vni_cmd);