#include "pbr_memory.h"
#include "pbr_zebra.h"
#include "pbr_debug.h"
+#include "pbr_vrf.h"
DEFINE_MTYPE_STATIC(PBRD, PBR_INTERFACE, "PBR Interface")
}
/* Inteface addition message from zebra. */
-static int interface_add(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+int pbr_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (!ifp)
- return 0;
-
DEBUGD(&pbr_dbg_zebra,
"%s: %s", __PRETTY_FUNCTION__, ifp->name);
if (!ifp->info)
pbr_if_new(ifp);
+ /* Update nexthops tracked from a `set nexthop` command */
pbr_nht_nexthop_interface_update(ifp);
+ pbr_map_policy_interface_update(ifp, true);
+
return 0;
}
-static int interface_delete(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+int pbr_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- /* zebra_interface_state_read () updates interface structure in iflist
- */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
DEBUGD(&pbr_dbg_zebra,
"%s: %s", __PRETTY_FUNCTION__, ifp->name);
- if_set_index(ifp, IFINDEX_INTERNAL);
+ pbr_map_policy_interface_update(ifp, false);
return 0;
}
-static int interface_address_add(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int interface_address_add(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
char buf[PREFIX_STRLEN];
- c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
+ c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
DEBUGD(&pbr_dbg_zebra,
"%s: %s added %s", __PRETTY_FUNCTION__,
return 0;
}
-static int interface_address_delete(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int interface_address_delete(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
char buf[PREFIX_STRLEN];
- c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
+ c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
if (!c)
return 0;
"%s: %s deleted %s", __PRETTY_FUNCTION__, c->ifp->name,
prefix2str(c->address, buf, sizeof(buf)));
- connected_free(c);
+ connected_free(&c);
return 0;
}
-static int interface_state_up(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+int pbr_ifp_up(struct interface *ifp)
{
- struct interface *ifp;
+ DEBUGD(&pbr_dbg_zebra,
+ "%s: %s is up", __PRETTY_FUNCTION__, ifp->name);
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
+ pbr_nht_nexthop_interface_update(ifp);
+ return 0;
+}
+
+int pbr_ifp_down(struct interface *ifp)
+{
DEBUGD(&pbr_dbg_zebra,
- "%s: %s is up", __PRETTY_FUNCTION__, ifp->name);
+ "%s: %s is down", __PRETTY_FUNCTION__, ifp->name);
pbr_nht_nexthop_interface_update(ifp);
return 0;
}
-static int interface_state_down(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int interface_vrf_update(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
+ vrf_id_t new_vrf_id;
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
+ ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
+ &new_vrf_id);
- DEBUGD(&pbr_dbg_zebra,
- "%s: %s is down", __PRETTY_FUNCTION__, ifp->name);
+ if (!ifp) {
+ DEBUGD(&pbr_dbg_zebra, "%s: VRF change interface not found",
+ __func__);
- pbr_nht_nexthop_interface_update(ifp);
+ return 0;
+ }
+
+ DEBUGD(&pbr_dbg_zebra, "%s: %s VRF change %u -> %u", __func__,
+ ifp->name, vrf_id, new_vrf_id);
+
+ if_update_to_new_vrf(ifp, new_vrf_id);
return 0;
}
-static int route_notify_owner(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int route_notify_owner(ZAPI_CALLBACK_ARGS)
{
struct prefix p;
enum zapi_route_notify_owner note;
return 0;
}
-static int rule_notify_owner(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int rule_notify_owner(ZAPI_CALLBACK_ARGS)
{
uint32_t seqno, priority, unique;
enum zapi_rule_notify_owner note;
"%s: Asked to install unsupported route type: L2VPN",
__PRETTY_FUNCTION__);
break;
+ case AFI_UNSPEC:
+ DEBUGD(&pbr_dbg_zebra,
+ "%s: Asked to install unspecified route type",
+ __PRETTY_FUNCTION__);
+ break;
}
}
"%s: Asked to delete unsupported route type: L2VPN",
__PRETTY_FUNCTION__);
break;
+ case AFI_UNSPEC:
+ DEBUGD(&pbr_dbg_zebra,
+ "%s: Asked to delete unspecified route type",
+ __PRETTY_FUNCTION__);
+ break;
}
}
-static int pbr_zebra_nexthop_update(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
{
struct zapi_route nhr;
char buf[PREFIX2STR_BUFFER];
zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs);
zclient->zebra_connected = zebra_connected;
- zclient->interface_add = interface_add;
- zclient->interface_delete = interface_delete;
- zclient->interface_up = interface_state_up;
- zclient->interface_down = interface_state_down;
zclient->interface_address_add = interface_address_add;
zclient->interface_address_delete = interface_address_delete;
+ zclient->interface_vrf_update = interface_vrf_update;
zclient->route_notify_owner = route_notify_owner;
zclient->rule_notify_owner = rule_notify_owner;
zclient->nexthop_update = pbr_zebra_nexthop_update;
p.family = AF_INET6;
memcpy(&p.u.prefix6, &nhop->gate.ipv6, 16);
p.prefixlen = 128;
+ if (IN6_IS_ADDR_LINKLOCAL(&nhop->gate.ipv6))
+ /*
+ * Don't bother tracking link locals, just track their
+ * interface state.
+ */
+ return;
break;
}
stream_put(s, &p->u.prefix, prefix_blen(p));
}
+static void
+pbr_encode_pbr_map_sequence_vrf(struct stream *s,
+ const struct pbr_map_sequence *pbrms,
+ const struct interface *ifp)
+{
+ struct pbr_vrf *pbr_vrf;
+
+ if (pbrms->vrf_unchanged)
+ pbr_vrf = pbr_vrf_lookup_by_id(ifp->vrf_id);
+ else
+ pbr_vrf = pbr_vrf_lookup_by_name(pbrms->vrf_name);
+
+ if (!pbr_vrf) {
+ DEBUGD(&pbr_dbg_zebra, "%s: VRF not found", __func__);
+ return;
+ }
+
+ stream_putl(s, pbr_vrf->vrf->data.l.table_id);
+}
+
static void pbr_encode_pbr_map_sequence(struct stream *s,
struct pbr_map_sequence *pbrms,
struct interface *ifp)
stream_putw(s, 0); /* src port */
pbr_encode_pbr_map_sequence_prefix(s, pbrms->dst, family);
stream_putw(s, 0); /* dst port */
- stream_putl(s, 0); /* fwmark */
- if (pbrms->nhgrp_name)
+ stream_putl(s, pbrms->mark);
+
+ if (pbrms->vrf_unchanged || pbrms->vrf_lookup)
+ pbr_encode_pbr_map_sequence_vrf(s, pbrms, ifp);
+ else if (pbrms->nhgrp_name)
stream_putl(s, pbr_nht_get_table(pbrms->nhgrp_name));
else if (pbrms->nhg)
stream_putl(s, pbr_nht_get_table(pbrms->internal_nhg_name));