forked from Mirror/frr
lib: if: track oper-state inline
Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
e64966876c
commit
80c6f98ea7
128
lib/if.c
128
lib/if.c
|
@ -29,6 +29,10 @@
|
|||
#include "admin_group.h"
|
||||
#include "lib/if_clippy.c"
|
||||
|
||||
|
||||
/* Set by the owner (zebra). */
|
||||
bool if_notify_oper_changes;
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, IF, "Interface");
|
||||
DEFINE_MTYPE_STATIC(LIB, IFDESC, "Intf Desc");
|
||||
DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected");
|
||||
|
@ -208,6 +212,104 @@ void if_down_via_zapi(struct interface *ifp)
|
|||
hook_call(if_down, ifp);
|
||||
}
|
||||
|
||||
void if_update_state_metric(struct interface *ifp, uint32_t metric)
|
||||
{
|
||||
if (ifp->metric == metric)
|
||||
return;
|
||||
ifp->metric = metric;
|
||||
if (ifp->state && if_notify_oper_changes)
|
||||
nb_op_updatef(ifp->state, "metric", "%u", ifp->metric);
|
||||
}
|
||||
|
||||
void if_update_state_mtu(struct interface *ifp, uint mtu)
|
||||
{
|
||||
if (ifp->mtu == mtu)
|
||||
return;
|
||||
ifp->mtu = mtu;
|
||||
if (ifp->state && if_notify_oper_changes)
|
||||
nb_op_updatef(ifp->state, "mtu", "%u", ifp->mtu);
|
||||
}
|
||||
|
||||
void if_update_state_mtu6(struct interface *ifp, uint mtu)
|
||||
{
|
||||
if (ifp->mtu6 == mtu)
|
||||
return;
|
||||
ifp->mtu6 = mtu;
|
||||
if (ifp->state && if_notify_oper_changes)
|
||||
nb_op_updatef(ifp->state, "mtu6", "%u", ifp->mtu);
|
||||
}
|
||||
|
||||
void if_update_state_hw_addr(struct interface *ifp, const uint8_t *hw_addr, uint len)
|
||||
{
|
||||
if (len == (uint)ifp->hw_addr_len && (len == 0 || !memcmp(hw_addr, ifp->hw_addr, len)))
|
||||
return;
|
||||
memcpy(ifp->hw_addr, hw_addr, len);
|
||||
ifp->hw_addr_len = len;
|
||||
if (ifp->state && if_notify_oper_changes)
|
||||
nb_op_updatef(ifp->state, "phy-address", "%pEA", (struct ethaddr *)ifp->hw_addr);
|
||||
}
|
||||
|
||||
void if_update_state_speed(struct interface *ifp, uint32_t speed)
|
||||
{
|
||||
if (ifp->speed == speed)
|
||||
return;
|
||||
ifp->speed = speed;
|
||||
if (ifp->state && if_notify_oper_changes)
|
||||
nb_op_updatef(ifp->state, "speed", "%u", ifp->speed);
|
||||
}
|
||||
|
||||
void if_update_state(struct interface *ifp)
|
||||
{
|
||||
struct lyd_node *state = ifp->state;
|
||||
|
||||
if (!state || !if_notify_oper_changes)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Remove top level container update when we have patch support, for now
|
||||
* this keeps us from generating 6 separate REPLACE messages though.
|
||||
*/
|
||||
// nb_op_update(state, ".", NULL);
|
||||
nb_op_updatef(state, "if-index", "%d", ifp->ifindex);
|
||||
nb_op_updatef(state, "mtu", "%u", ifp->mtu);
|
||||
nb_op_updatef(state, "mtu6", "%u", ifp->mtu);
|
||||
nb_op_updatef(state, "speed", "%u", ifp->speed);
|
||||
nb_op_updatef(state, "metric", "%u", ifp->metric);
|
||||
nb_op_updatef(state, "phy-address", "%pEA", (struct ethaddr *)ifp->hw_addr);
|
||||
}
|
||||
|
||||
static void if_update_state_remove(struct interface *ifp)
|
||||
{
|
||||
if (!if_notify_oper_changes || ifp->name[0] == 0)
|
||||
return;
|
||||
|
||||
if (vrf_is_backend_netns())
|
||||
nb_op_update_delete_pathf(NULL, "/frr-interface:lib/interface[name=\"%s:%s\"]/state",
|
||||
ifp->vrf->name, ifp->name);
|
||||
else
|
||||
nb_op_update_delete_pathf(NULL, "/frr-interface:lib/interface[name=\"%s\"]/state",
|
||||
ifp->name);
|
||||
if (ifp->state) {
|
||||
lyd_free_all(ifp->state);
|
||||
ifp->state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void if_update_state_add(struct interface *ifp)
|
||||
{
|
||||
if (!if_notify_oper_changes || ifp->name[0] == 0)
|
||||
return;
|
||||
|
||||
if (vrf_is_backend_netns())
|
||||
ifp->state = nb_op_update_pathf(NULL,
|
||||
"/frr-interface:lib/interface[name=\"%s:%s\"]/state",
|
||||
NULL, ifp->vrf->name, ifp->name);
|
||||
else
|
||||
ifp->state = nb_op_update_pathf(NULL,
|
||||
"/frr-interface:lib/interface[name=\"%s\"]/state",
|
||||
NULL, ifp->name);
|
||||
}
|
||||
|
||||
static struct interface *if_create_name(const char *name, struct vrf *vrf)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
@ -216,7 +318,11 @@ static struct interface *if_create_name(const char *name, struct vrf *vrf)
|
|||
|
||||
if_set_name(ifp, name);
|
||||
|
||||
if (if_notify_oper_changes && ifp->state)
|
||||
if_update_state(ifp);
|
||||
|
||||
hook_call(if_add, ifp);
|
||||
|
||||
return ifp;
|
||||
}
|
||||
|
||||
|
@ -228,8 +334,10 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
|
|||
/* remove interface from old master vrf list */
|
||||
old_vrf = ifp->vrf;
|
||||
|
||||
if (ifp->name[0] != '\0')
|
||||
if (ifp->name[0] != '\0') {
|
||||
IFNAME_RB_REMOVE(old_vrf, ifp);
|
||||
if_update_state_remove(ifp);
|
||||
}
|
||||
|
||||
if (ifp->ifindex != IFINDEX_INTERNAL)
|
||||
IFINDEX_RB_REMOVE(old_vrf, ifp);
|
||||
|
@ -237,8 +345,11 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
|
|||
vrf = vrf_get(vrf_id, NULL);
|
||||
ifp->vrf = vrf;
|
||||
|
||||
if (ifp->name[0] != '\0')
|
||||
if (ifp->name[0] != '\0') {
|
||||
IFNAME_RB_INSERT(vrf, ifp);
|
||||
if_update_state_add(ifp);
|
||||
if_update_state(ifp);
|
||||
}
|
||||
|
||||
if (ifp->ifindex != IFINDEX_INTERNAL)
|
||||
IFINDEX_RB_INSERT(vrf, ifp);
|
||||
|
@ -280,6 +391,8 @@ void if_delete(struct interface **ifp)
|
|||
|
||||
XFREE(MTYPE_IFDESC, ptr->desc);
|
||||
|
||||
if_update_state_remove(ptr);
|
||||
|
||||
XFREE(MTYPE_IF, ptr);
|
||||
*ifp = NULL;
|
||||
}
|
||||
|
@ -630,6 +743,9 @@ int if_set_index(struct interface *ifp, ifindex_t ifindex)
|
|||
|
||||
ifp->ifindex = ifindex;
|
||||
|
||||
if (if_notify_oper_changes)
|
||||
nb_op_updatef(ifp->state, "if-index", "%d", ifp->ifindex);
|
||||
|
||||
if (ifp->ifindex != IFINDEX_INTERNAL) {
|
||||
/*
|
||||
* This should never happen, since we checked if there was
|
||||
|
@ -648,13 +764,17 @@ static void if_set_name(struct interface *ifp, const char *name)
|
|||
if (if_cmp_name_func(ifp->name, name) == 0)
|
||||
return;
|
||||
|
||||
if (ifp->name[0] != '\0')
|
||||
if (ifp->name[0] != '\0') {
|
||||
IFNAME_RB_REMOVE(ifp->vrf, ifp);
|
||||
if_update_state_remove(ifp);
|
||||
}
|
||||
|
||||
strlcpy(ifp->name, name, sizeof(ifp->name));
|
||||
|
||||
if (ifp->name[0] != '\0')
|
||||
if (ifp->name[0] != '\0') {
|
||||
IFNAME_RB_INSERT(ifp->vrf, ifp);
|
||||
if_update_state_add(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Does interface up ? */
|
||||
|
|
10
lib/if.h
10
lib/if.h
|
@ -297,6 +297,8 @@ struct interface {
|
|||
|
||||
struct vrf *vrf;
|
||||
|
||||
struct lyd_node *state;
|
||||
|
||||
/*
|
||||
* Has the end users entered `interface XXXX` from the cli in some
|
||||
* fashion?
|
||||
|
@ -633,6 +635,14 @@ extern void if_up_via_zapi(struct interface *ifp);
|
|||
extern void if_down_via_zapi(struct interface *ifp);
|
||||
extern void if_destroy_via_zapi(struct interface *ifp);
|
||||
|
||||
extern void if_update_state(struct interface *ifp);
|
||||
extern void if_update_state_metric(struct interface *ifp, uint32_t metric);
|
||||
extern void if_update_state_mtu(struct interface *ifp, uint mtu);
|
||||
extern void if_update_state_mtu6(struct interface *ifp, uint mtu);
|
||||
extern void if_update_state_hw_addr(struct interface *ifp, const uint8_t *hw_addr, uint len);
|
||||
extern void if_update_state_speed(struct interface *ifp, uint32_t speed);
|
||||
|
||||
extern bool if_notify_oper_changes;
|
||||
extern const struct frr_yang_module_info frr_interface_info;
|
||||
extern const struct frr_yang_module_info frr_interface_cli_info;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ static void if_zebra_speed_update(struct event *thread)
|
|||
if (new_speed != ifp->speed) {
|
||||
zlog_info("%s: %s old speed: %u new speed: %u", __func__,
|
||||
ifp->name, ifp->speed, new_speed);
|
||||
ifp->speed = new_speed;
|
||||
if_update_state_speed(ifp, new_speed);
|
||||
if_add_update(ifp);
|
||||
changed = true;
|
||||
}
|
||||
|
@ -1563,17 +1563,20 @@ static inline void zebra_if_set_ziftype(struct interface *ifp,
|
|||
static void interface_update_hw_addr(struct zebra_dplane_ctx *ctx,
|
||||
struct interface *ifp)
|
||||
{
|
||||
int i;
|
||||
uint8_t hw_addr[INTERFACE_HWADDR_MAX];
|
||||
uint i, hw_addr_len;
|
||||
|
||||
ifp->hw_addr_len = dplane_ctx_get_ifp_hw_addr_len(ctx);
|
||||
memcpy(ifp->hw_addr, dplane_ctx_get_ifp_hw_addr(ctx), ifp->hw_addr_len);
|
||||
hw_addr_len = dplane_ctx_get_ifp_hw_addr_len(ctx);
|
||||
memcpy(hw_addr, dplane_ctx_get_ifp_hw_addr(ctx), hw_addr_len);
|
||||
|
||||
for (i = 0; i < ifp->hw_addr_len; i++)
|
||||
if (ifp->hw_addr[i] != 0)
|
||||
for (i = 0; i < hw_addr_len; i++)
|
||||
if (hw_addr[i] != 0)
|
||||
break;
|
||||
|
||||
if (i == ifp->hw_addr_len)
|
||||
ifp->hw_addr_len = 0;
|
||||
if (i == hw_addr_len)
|
||||
hw_addr_len = 0;
|
||||
|
||||
if_update_state_hw_addr(ifp, hw_addr, hw_addr_len);
|
||||
}
|
||||
|
||||
static void interface_update_l2info(struct zebra_dplane_ctx *ctx,
|
||||
|
@ -1984,9 +1987,10 @@ static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx)
|
|||
/* Update interface information. */
|
||||
set_ifindex(ifp, ifindex, zns);
|
||||
ifp->flags = flags;
|
||||
ifp->mtu6 = ifp->mtu = mtu;
|
||||
ifp->metric = 0;
|
||||
ifp->speed = kernel_get_speed(ifp, NULL);
|
||||
if_update_state_mtu(ifp, mtu);
|
||||
if_update_state_mtu6(ifp, mtu);
|
||||
if_update_state_metric(ifp, 0);
|
||||
if_update_state_speed(ifp, kernel_get_speed(ifp, NULL));
|
||||
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
|
||||
ifp->txqlen = dplane_ctx_get_intf_txqlen(ctx);
|
||||
|
||||
|
@ -2036,6 +2040,7 @@ static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx)
|
|||
IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(
|
||||
zif));
|
||||
}
|
||||
// if_update_state(ifp);
|
||||
} else if (ifp->vrf->vrf_id != vrf_id) {
|
||||
/* VRF change for an interface. */
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
|
@ -2058,8 +2063,9 @@ static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx)
|
|||
(unsigned long long)flags);
|
||||
|
||||
set_ifindex(ifp, ifindex, zns);
|
||||
ifp->mtu6 = ifp->mtu = mtu;
|
||||
ifp->metric = 0;
|
||||
if_update_state_mtu(ifp, mtu);
|
||||
if_update_state_mtu6(ifp, mtu);
|
||||
if_update_state_metric(ifp, 0);
|
||||
ifp->txqlen = dplane_ctx_get_intf_txqlen(ctx);
|
||||
|
||||
/*
|
||||
|
|
|
@ -356,6 +356,7 @@ int main(int argc, char **argv)
|
|||
|
||||
zserv_path = NULL;
|
||||
|
||||
if_notify_oper_changes = true;
|
||||
vrf_notify_oper_changes = true;
|
||||
|
||||
vrf_configure_backend(VRF_BACKEND_VRF_LITE);
|
||||
|
|
Loading…
Reference in a new issue