diff options
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 @@ -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 @@ -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); |
