diff options
Diffstat (limited to 'zebra/interface.c')
| -rw-r--r-- | zebra/interface.c | 125 |
1 files changed, 102 insertions, 23 deletions
diff --git a/zebra/interface.c b/zebra/interface.c index 12312ff43a..1bafb4c59d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -242,7 +242,7 @@ int if_subnet_add(struct interface *ifp, struct connected *ifc) /* Get address derived subnet node and associated address list, while marking address secondary attribute appropriately. */ - cp = *ifc->address; + cp = *CONNECTED_PREFIX(ifc); apply_mask(&cp); rn = route_node_get(zebra_if->ipv4_subnets, &cp); @@ -267,12 +267,16 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc) struct route_node *rn; struct zebra_if *zebra_if; struct list *addr_list; + struct prefix cp; assert(ifp && ifp->info && ifc); zebra_if = ifp->info; + cp = *CONNECTED_PREFIX(ifc); + apply_mask(&cp); + /* Get address derived subnet node. */ - rn = route_node_lookup(zebra_if->ipv4_subnets, ifc->address); + rn = route_node_lookup(zebra_if->ipv4_subnets, &cp); if (!(rn && rn->info)) { zlog_warn( "Trying to remove an address from an unknown subnet." @@ -565,7 +569,7 @@ static void if_uninstall_connected(struct interface *ifp) static void if_delete_connected(struct interface *ifp) { struct connected *ifc; - struct prefix *p; + struct prefix cp; struct route_node *rn; struct zebra_if *zebra_if; @@ -578,11 +582,13 @@ static void if_delete_connected(struct interface *ifp) while ((node = (last ? last->next : listhead(ifp->connected)))) { ifc = listgetdata(node); - p = ifc->address; - if (p->family == AF_INET + cp = *CONNECTED_PREFIX(ifc); + apply_mask(&cp); + + if (cp.family == AF_INET && (rn = route_node_lookup(zebra_if->ipv4_subnets, - p))) { + &cp))) { struct listnode *anode; struct listnode *next; struct listnode *first; @@ -635,7 +641,7 @@ static void if_delete_connected(struct interface *ifp) list_delete(addr_list); rn->info = NULL; route_unlock_node(rn); - } else if (p->family == AF_INET6) { + } else if (cp.family == AF_INET6) { connected_down_ipv6(ifp, ifc); zebra_interface_address_delete_update(ifp, ifc); @@ -873,7 +879,8 @@ void if_up(struct interface *ifp) link_if = ifp; zebra_vxlan_svi_up(ifp, link_if); } else if (IS_ZEBRA_IF_VLAN(ifp)) { - link_if = zif->link; + link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + zif->link_ifindex); if (link_if) zebra_vxlan_svi_up(ifp, link_if); } @@ -901,7 +908,8 @@ void if_down(struct interface *ifp) link_if = ifp; zebra_vxlan_svi_down(ifp, link_if); } else if (IS_ZEBRA_IF_VLAN(ifp)) { - link_if = zif->link; + link_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + zif->link_ifindex); if (link_if) zebra_vxlan_svi_down(ifp, link_if); } @@ -966,6 +974,8 @@ static void connected_dump_vty(struct vty *vty, struct connected *connected) vty_out(vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast ")); prefix_vty_out(vty, connected->destination); + if (CONNECTED_PEER(connected)) + vty_out(vty, "/%d", connected->destination->prefixlen); } if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY)) @@ -2365,38 +2375,56 @@ static int ip_address_install(struct vty *vty, struct interface *ifp, const char *label) { struct zebra_if *if_data; - struct prefix_ipv4 cp; + struct prefix_ipv4 lp, pp; struct connected *ifc; struct prefix_ipv4 *p; int ret; if_data = ifp->info; - ret = str2prefix_ipv4(addr_str, &cp); + ret = str2prefix_ipv4(addr_str, &lp); if (ret <= 0) { vty_out(vty, "%% Malformed address \n"); return CMD_WARNING_CONFIG_FAILED; } - if (ipv4_martian(&cp.prefix)) { + if (ipv4_martian(&lp.prefix)) { vty_out(vty, "%% Invalid address\n"); return CMD_WARNING_CONFIG_FAILED; } - ifc = connected_check(ifp, (struct prefix *)&cp); + if (peer_str) { + if (lp.prefixlen != 32) { + vty_out(vty, + "%% Local prefix length for P-t-P address must be /32\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = str2prefix_ipv4(peer_str, &pp); + if (ret <= 0) { + vty_out(vty, "%% Malformed peer address\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL); if (!ifc) { ifc = connected_new(); ifc->ifp = ifp; /* Address. */ p = prefix_ipv4_new(); - *p = cp; + *p = lp; ifc->address = (struct prefix *)p; - /* Broadcast. */ - if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) { + if (peer_str) { + SET_FLAG(ifc->flags, ZEBRA_IFA_PEER); + p = prefix_ipv4_new(); + *p = pp; + ifc->destination = (struct prefix *)p; + } else if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) { p = prefix_ipv4_new(); - *p = cp; + *p = lp; p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr, p->prefixlen); ifc->destination = (struct prefix *)p; @@ -2445,19 +2473,33 @@ static int ip_address_uninstall(struct vty *vty, struct interface *ifp, const char *addr_str, const char *peer_str, const char *label) { - struct prefix_ipv4 cp; + struct prefix_ipv4 lp, pp; struct connected *ifc; int ret; /* Convert to prefix structure. */ - ret = str2prefix_ipv4(addr_str, &cp); + ret = str2prefix_ipv4(addr_str, &lp); if (ret <= 0) { vty_out(vty, "%% Malformed address \n"); return CMD_WARNING_CONFIG_FAILED; } + if (peer_str) { + if (lp.prefixlen != 32) { + vty_out(vty, + "%% Local prefix length for P-t-P address must be /32\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = str2prefix_ipv4(peer_str, &pp); + if (ret <= 0) { + vty_out(vty, "%% Malformed peer address\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + /* Check current interface address. */ - ifc = connected_check(ifp, (struct prefix *)&cp); + ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL); if (!ifc) { vty_out(vty, "%% Can't find address\n"); return CMD_WARNING_CONFIG_FAILED; @@ -2517,6 +2559,32 @@ DEFUN (no_ip_address, NULL, NULL); } +DEFUN (ip_address_peer, + ip_address_peer_cmd, + "ip address A.B.C.D peer A.B.C.D/M", + "Interface Internet Protocol config commands\n" + "Set the IP address of an interface\n" + "Local IP (e.g. 10.0.0.1) for P-t-P address\n" + "Specify P-t-P address\n" + "Peer IP address (e.g. 10.0.0.1/8)\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL); +} + +DEFUN (no_ip_address_peer, + no_ip_address_peer_cmd, + "no ip address A.B.C.D peer A.B.C.D/M", + NO_STR + "Interface Internet Protocol config commands\n" + "Set the IP address of an interface\n" + "Local IP (e.g. 10.0.0.1) for P-t-P address\n" + "Specify P-t-P address\n" + "Peer IP address (e.g. 10.0.0.1/8)\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL); +} #ifdef HAVE_NETLINK DEFUN (ip_address_label, @@ -2791,7 +2859,7 @@ static int if_config_write(struct vty *vty) vrf = vrf_lookup_by_id(ifp->vrf_id); if (ifp->vrf_id == VRF_DEFAULT) - vty_out(vty, "interface %s\n", ifp->name); + vty_frame(vty, "interface %s\n", ifp->name); else vty_out(vty, "interface %s vrf %s\n", ifp->name, vrf->name); @@ -2820,7 +2888,16 @@ static int if_config_write(struct vty *vty) p = ifc->address; vty_out(vty, " ip%s address %s", p->family == AF_INET ? "" : "v6", - prefix2str(p, buf, sizeof(buf))); + inet_ntop(p->family, &p->u.prefix, + buf, sizeof(buf))); + if (CONNECTED_PEER (ifc)) { + p = ifc->destination; + vty_out(vty, " peer %s", + inet_ntop(p->family, + &p->u.prefix, + buf, sizeof(buf))); + } + vty_out (vty, "/%d", p->prefixlen); if (ifc->label) vty_out(vty, " label %s", ifc->label); @@ -2842,7 +2919,7 @@ static int if_config_write(struct vty *vty) link_params_config_write(vty, ifp); - vty_out(vty, "!\n"); + vty_endframe(vty, "!\n"); } return 0; } @@ -2876,6 +2953,8 @@ void zebra_if_init(void) install_element(INTERFACE_NODE, &no_bandwidth_if_cmd); install_element(INTERFACE_NODE, &ip_address_cmd); install_element(INTERFACE_NODE, &no_ip_address_cmd); + install_element(INTERFACE_NODE, &ip_address_peer_cmd); + install_element(INTERFACE_NODE, &no_ip_address_peer_cmd); install_element(INTERFACE_NODE, &ipv6_address_cmd); install_element(INTERFACE_NODE, &no_ipv6_address_cmd); #ifdef HAVE_NETLINK |
