summaryrefslogtreecommitdiff
path: root/zebra/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/interface.c')
-rw-r--r--zebra/interface.c125
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