summaryrefslogtreecommitdiff
path: root/lib/if.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/if.c')
-rw-r--r--lib/if.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/lib/if.c b/lib/if.c
index 86b850c059..3f489e0c3e 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -187,18 +187,21 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
if (yang_module_find("frr-interface")) {
struct lyd_node *if_dnode;
- if_dnode = yang_dnode_get(
- running_config->dnode,
- "/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
- ifp->name, old_vrf->name);
- if (if_dnode) {
- yang_dnode_change_leaf(if_dnode, vrf->name);
- running_config->version++;
+ pthread_rwlock_wrlock(&running_config->lock);
+ {
+ if_dnode = yang_dnode_get(
+ running_config->dnode,
+ "/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
+ ifp->name, old_vrf->name);
+ if (if_dnode) {
+ yang_dnode_change_leaf(if_dnode, vrf->name);
+ running_config->version++;
+ }
}
+ pthread_rwlock_unlock(&running_config->lock);
}
}
-
/* Delete interface structure. */
void if_delete_retain(struct interface *ifp)
{
@@ -386,6 +389,34 @@ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id)
return NULL;
}
+size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz,
+ struct interface ***result, vrf_id_t vrf_id)
+{
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+ struct list *rs = list_new();
+ struct interface *ifp;
+
+ FOR_ALL_INTERFACES (vrf, ifp) {
+ if (ifp->hw_addr_len == (int)addrsz
+ && !memcmp(hw_addr, ifp->hw_addr, addrsz))
+ listnode_add(rs, ifp);
+ }
+
+ if (rs->count) {
+ *result = XCALLOC(MTYPE_TMP,
+ sizeof(struct interface *) * rs->count);
+ list_to_array(rs, (void **)*result, rs->count);
+ }
+
+ int count = rs->count;
+
+ list_delete(&rs);
+
+ return count;
+}
+
+
/* Get interface by name if given name interface doesn't exist create
one. */
struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id)
@@ -873,6 +904,19 @@ struct connected *connected_add_by_prefix(struct interface *ifp,
return ifc;
}
+struct connected *connected_get_linklocal(struct interface *ifp)
+{
+ struct listnode *n;
+ struct connected *c = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
+ if (c->address->family == AF_INET6
+ && IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
+ break;
+ }
+ return c;
+}
+
#if 0 /* this route_table of struct connected's is unused \
* however, it would be good to use a route_table rather than \
* a list.. \