0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Kernel preferred interface address updater decoupled from the lib

This commit is contained in:
Maria Matejka 2024-09-02 11:52:00 +02:00
parent 60bd75c174
commit edd9ec599c
7 changed files with 41 additions and 35 deletions

View File

@ -32,7 +32,6 @@
#include "lib/string.h" #include "lib/string.h"
#include "lib/locking.h" #include "lib/locking.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "sysdep/unix/krt.h"
DOMAIN(attrs) iface_domain; DOMAIN(attrs) iface_domain;
@ -780,6 +779,8 @@ if_set_preferred(struct ifa **pos, struct ifa *new)
*pos = new; *pos = new;
} }
int (*kif_update_sysdep_addr)(struct iface *) = NULL;
static void static void
if_recalc_preferred(struct iface *i) if_recalc_preferred(struct iface *i)
{ {
@ -789,14 +790,14 @@ if_recalc_preferred(struct iface *i)
* 2) Sysdep IPv4 address (BSD) * 2) Sysdep IPv4 address (BSD)
* 3) Old preferred address * 3) Old preferred address
* 4) First address in list * 4) First address in list
*/ */
struct kif_iface_config *ic = kif_get_iface_config(i); struct iface_config *ic = i->cf;
struct ifa *a4 = i->addr4, *a6 = i->addr6, *ll = i->llv6; struct ifa *a4 = i->addr4, *a6 = i->addr6, *ll = i->llv6;
ip_addr pref_v4 = ic->pref_v4; ip_addr pref_v4 = ic->pref_v4;
uint change = 0; uint change = 0;
if (kif_update_sysdep_addr(i)) if (kif_update_sysdep_addr && kif_update_sysdep_addr(i))
change |= IF_CHANGE_SYSDEP; change |= IF_CHANGE_SYSDEP;
/* BSD sysdep address */ /* BSD sysdep address */

View File

@ -45,10 +45,14 @@ struct iface {
struct ifa *addr6; /* Primary address for IPv6 */ struct ifa *addr6; /* Primary address for IPv6 */
struct ifa *llv6; /* Primary link-local address for IPv6 */ struct ifa *llv6; /* Primary link-local address for IPv6 */
ip4_addr sysdep; /* Arbitrary IPv4 address for internal sysdep use */ ip4_addr sysdep; /* Arbitrary IPv4 address for internal sysdep use */
struct iface_config *cf; /* Attached configuration */
list neighbors; /* All neighbors on this interface */ list neighbors; /* All neighbors on this interface */
unsigned uc; /* Use (link) count */ unsigned uc; /* Use (link) count */
}; };
/* Sysdep address updater */
extern int (*kif_update_sysdep_addr)(struct iface *);
#define IF_UP 1 /* Currently just IF_ADMIN_UP */ #define IF_UP 1 /* Currently just IF_ADMIN_UP */
#define IF_MULTIACCESS 2 #define IF_MULTIACCESS 2
#define IF_BROADCAST 4 #define IF_BROADCAST 4
@ -262,6 +266,15 @@ int iface_patt_match(struct iface_patt *ifp, struct iface *i, struct ifa *a);
struct iface_patt *iface_patt_find(list *l, struct iface *i, struct ifa *a); struct iface_patt *iface_patt_find(list *l, struct iface *i, struct ifa *a);
int iface_patts_equal(list *, list *, int (*)(struct iface_patt *, struct iface_patt *)); int iface_patts_equal(list *, list *, int (*)(struct iface_patt *, struct iface_patt *));
/* Basic interface configuration */
struct iface_config {
struct iface_patt i;
ip_addr pref_v4;
ip_addr pref_v6;
ip_addr pref_ll;
};
u32 if_choose_router_id(struct iface_patt *mask, u32 old_id); u32 if_choose_router_id(struct iface_patt *mask, u32 old_id);

View File

@ -745,6 +745,8 @@ krt_read_ifinfo(struct ks_msg *msg, int scan)
if (fl & IFF_MULTICAST) if (fl & IFF_MULTICAST)
f.flags |= IF_MULTICAST; f.flags |= IF_MULTICAST;
f.cf = kif_get_iface_config(&f);
iface = if_update(&f); iface = if_update(&f);
if (!scan) if (!scan)
@ -1220,19 +1222,14 @@ void krt_sys_copy_config(struct krt_config *d, struct krt_config *s)
/* KIF misc code */ /* KIF misc code */
void
kif_sys_start(struct kif_proto *p UNUSED)
{
}
void void
kif_sys_shutdown(struct kif_proto *p) kif_sys_shutdown(struct kif_proto *p)
{ {
krt_buffer_release(&p->p); krt_buffer_release(&p->p);
} }
int static int
kif_update_sysdep_addr(struct iface *i) kif_update_sysdep_addr_(struct iface *i)
{ {
static int fd = -1; static int fd = -1;
@ -1252,3 +1249,10 @@ kif_update_sysdep_addr(struct iface *i)
return !ip4_equal(i->sysdep, old); return !ip4_equal(i->sysdep, old);
} }
void
kif_sys_start(struct kif_proto *p UNUSED)
{
/* Setup sysdep address updater */
kif_update_sysdep_addr = kif_update_sysdep_addr_;
}

View File

@ -1101,6 +1101,8 @@ nl_parse_link(struct nlmsghdr *h, int scan)
if (kind && !strcmp(kind, "vrf")) if (kind && !strcmp(kind, "vrf"))
f.flags |= IF_VRF; f.flags |= IF_VRF;
f.cf = kif_get_iface_config(&f);
ifi = if_update(&f); ifi = if_update(&f);
if (!scan) if (!scan)
@ -1354,6 +1356,8 @@ kif_do_scan(struct kif_proto *p UNUSED)
if (f.master != i->master) if (f.master != i->master)
{ {
f.cf = kif_get_iface_config(&f);
memcpy(f.name, i->name, sizeof(f.name)); memcpy(f.name, i->name, sizeof(f.name));
if_update_locked(&f); if_update_locked(&f);
} }
@ -2224,9 +2228,3 @@ void
kif_sys_shutdown(struct kif_proto *p UNUSED) kif_sys_shutdown(struct kif_proto *p UNUSED)
{ {
} }
int
kif_update_sysdep_addr(struct iface *i UNUSED)
{
return 0;
}

View File

@ -14,7 +14,7 @@ CF_DEFINES
#define THIS_KRT ((struct krt_config *) this_proto) #define THIS_KRT ((struct krt_config *) this_proto)
#define THIS_KIF ((struct kif_config *) this_proto) #define THIS_KIF ((struct kif_config *) this_proto)
#define KIF_IFACE ((struct kif_iface_config *) this_ipatt) #define KIF_IFACE ((struct iface_config *) this_ipatt)
static void static void
kif_set_preferred(ip_addr ip) kif_set_preferred(ip_addr ip)
@ -112,7 +112,7 @@ kif_item:
kif_iface_start: kif_iface_start:
{ {
this_ipatt = cfg_allocz(sizeof(struct kif_iface_config)); this_ipatt = cfg_allocz(sizeof(struct iface_config));
add_tail(&THIS_KIF->iface_list, NODE this_ipatt); add_tail(&THIS_KIF->iface_list, NODE this_ipatt);
init_list(&this_ipatt->ipn_list); init_list(&this_ipatt->ipn_list);
} }

View File

@ -89,13 +89,13 @@ static struct kif_config *kif_cf;
static timer *kif_scan_timer; static timer *kif_scan_timer;
static btime kif_last_shot; static btime kif_last_shot;
static struct kif_iface_config kif_default_iface = {}; static struct iface_config kif_default_iface = {};
struct kif_iface_config * struct iface_config *
kif_get_iface_config(struct iface *iface) kif_get_iface_config(struct iface *iface)
{ {
struct kif_config *cf = (void *) (kif_proto->p.cf); struct kif_config *cf = (void *) (kif_proto->p.cf);
struct kif_iface_config *ic = (void *) iface_patt_find(&cf->iface_list, iface, NULL); struct iface_config *ic = (void *) iface_patt_find(&cf->iface_list, iface, NULL);
return ic ?: &kif_default_iface; return ic ?: &kif_default_iface;
} }
@ -232,7 +232,7 @@ kif_copy_config(struct proto_config *dest, struct proto_config *src)
struct kif_config *s = (struct kif_config *) src; struct kif_config *s = (struct kif_config *) src;
/* Copy interface config list */ /* Copy interface config list */
cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct kif_iface_config)); cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_config));
/* Fix sysdep parts */ /* Fix sysdep parts */
kif_sys_copy_config(d, s); kif_sys_copy_config(d, s);

View File

@ -106,18 +106,10 @@ struct kif_config {
struct proto_config c; struct proto_config c;
struct kif_params sys; /* Sysdep params */ struct kif_params sys; /* Sysdep params */
list iface_list; /* List of iface configs (struct kif_iface_config) */ list iface_list; /* List of iface configs (struct iface_config) */
btime scan_time; /* How often we re-scan interfaces */ btime scan_time; /* How often we re-scan interfaces */
}; };
struct kif_iface_config {
struct iface_patt i;
ip_addr pref_v4;
ip_addr pref_v6;
ip_addr pref_ll;
};
struct kif_proto { struct kif_proto {
struct proto p; struct proto p;
struct kif_state sys; /* Sysdep state */ struct kif_state sys; /* Sysdep state */
@ -127,7 +119,7 @@ extern struct kif_proto *kif_proto;
#define KIF_CF ((struct kif_config *)p->p.cf) #define KIF_CF ((struct kif_config *)p->p.cf)
struct kif_iface_config * kif_get_iface_config(struct iface *iface); struct iface_config * kif_get_iface_config(struct iface *iface);
struct proto_config * krt_init_config(int class); struct proto_config * krt_init_config(int class);
@ -162,6 +154,4 @@ void kif_sys_copy_config(struct kif_config *, struct kif_config *);
void kif_do_scan(struct kif_proto *); void kif_do_scan(struct kif_proto *);
int kif_update_sysdep_addr(struct iface *i);
#endif #endif