Skip to content

Commit 9b5271c

Browse files
committed
move autoselect prefix code from gram.y to send.c
This solve the problem of new prefixes not being discovered after the config file was read.
1 parent dc3d2c1 commit 9b5271c

File tree

8 files changed

+198
-283
lines changed

8 files changed

+198
-283
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
2016/09/18 Moved auto prefix code from config file parse to send_ra.
2+
13
2016/08/08 Merged ARPHRD_6LOWPAN netlink query from <Alexander Aring>
24
Add systemd service file <Craig Andrews>
35

gram.y

Lines changed: 31 additions & 246 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
#include "defaults.h"
2020

2121
#define YYERROR_VERBOSE 1
22-
static int countbits(int b);
23-
static int count_mask(struct sockaddr_in6 *m);
24-
static struct in6_addr get_prefix6(struct in6_addr const *addr, struct in6_addr const *mask);
2522

2623
#if 0 /* no longer necessary? */
2724
#ifndef HAVE_IN6_ADDR_S6_ADDR
@@ -375,84 +372,12 @@ prefixdef : prefixhead optional_prefixplist ';'
375372
ABORT;
376373
}
377374

378-
if ( prefix->if6[0] && prefix->if6to4[0]) {
379-
flog(LOG_ERR, "Base6Interface and Base6to4Interface are mutually exclusive at this time");
380-
ABORT;
381-
}
382-
383-
if ( prefix->if6to4[0] )
384-
{
385-
if (get_v4addr(prefix->if6to4, &dst) < 0)
386-
{
387-
flog(LOG_ERR, "interface %s has no IPv4 addresses, disabling 6to4 prefix", prefix->if6to4 );
388-
prefix->enabled = 0;
389-
}
390-
else
391-
{
392-
*((uint16_t *)(prefix->Prefix.s6_addr)) = htons(0x2002);
393-
memcpy( prefix->Prefix.s6_addr + 2, &dst, sizeof( dst ) );
394-
}
395-
}
396-
397375
if ( prefix->if6[0] )
398376
{
399-
#ifndef HAVE_IFADDRS_H
400-
flog(LOG_ERR, "Base6Interface not supported in %s, line %d", filename, num_lines);
401-
ABORT;
402-
#else
403-
struct ifaddrs *ifap = 0, *ifa = 0;
404-
struct AdvPrefix *next = prefix->next;
405-
406377
if (prefix->PrefixLen != 64) {
407378
flog(LOG_ERR, "only /64 is allowed with Base6Interface. %s:%d", filename, num_lines);
408379
ABORT;
409380
}
410-
411-
if (getifaddrs(&ifap) != 0)
412-
flog(LOG_ERR, "getifaddrs failed: %s", strerror(errno));
413-
414-
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
415-
struct sockaddr_in6 *s6 = 0;
416-
struct sockaddr_in6 *mask = (struct sockaddr_in6 *)ifa->ifa_netmask;
417-
struct in6_addr base6prefix;
418-
char buf[INET6_ADDRSTRLEN];
419-
int i;
420-
421-
if (strncmp(ifa->ifa_name, prefix->if6, IFNAMSIZ))
422-
continue;
423-
424-
if (ifa->ifa_addr->sa_family != AF_INET6)
425-
continue;
426-
427-
s6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
428-
429-
if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr))
430-
continue;
431-
432-
base6prefix = get_prefix6(&s6->sin6_addr, &mask->sin6_addr);
433-
for (i = 0; i < 8; ++i) {
434-
prefix->Prefix.s6_addr[i] &= ~mask->sin6_addr.s6_addr[i];
435-
prefix->Prefix.s6_addr[i] |= base6prefix.s6_addr[i];
436-
}
437-
memset(&prefix->Prefix.s6_addr[8], 0, 8);
438-
prefix->AdvRouterAddr = 1;
439-
prefix->AutoSelected = 1;
440-
prefix->next = next;
441-
442-
if (inet_ntop(ifa->ifa_addr->sa_family, (void *)&(prefix->Prefix), buf, sizeof(buf)) == NULL)
443-
flog(LOG_ERR, "%s: inet_ntop failed in %s, line %d!", ifa->ifa_name, filename, num_lines);
444-
else
445-
dlog(LOG_DEBUG, 3, "auto-selected prefix %s/%d on interface %s from interface %s",
446-
buf, prefix->PrefixLen, iface->props.name, ifa->ifa_name);
447-
448-
/* Taking only one prefix from the Base6Interface. Taking more than one would require allocating new
449-
prefixes and building a list. I'm not sure how to do that from here. So for now, break. */
450-
break;
451-
}
452-
453-
if (ifap)
454-
freeifaddrs(ifap);
455-
#endif /* ifndef HAVE_IFADDRS_H */
456381
}
457382
}
458383
$$ = prefix;
@@ -466,94 +391,26 @@ prefixhead : T_PREFIX IPV6ADDR '/' NUMBER
466391
memset(&zeroaddr, 0, sizeof(zeroaddr));
467392

468393
if (!memcmp($2, &zeroaddr, sizeof(struct in6_addr))) {
469-
#ifndef HAVE_IFADDRS_H
470-
flog(LOG_ERR, "invalid all-zeros prefix in %s, line %d", filename, num_lines);
471-
ABORT;
472-
#else
473-
struct ifaddrs *ifap = 0, *ifa = 0;
474-
struct AdvPrefix *next = iface->AdvPrefixList;
475-
476-
while (next) {
477-
if (next->AutoSelected) {
478-
flog(LOG_ERR, "auto selecting prefixes works only once per interface. See %s, line %d", filename, num_lines);
479-
ABORT;
480-
}
481-
next = next->next;
482-
}
483-
next = 0;
484-
485-
dlog(LOG_DEBUG, 5, "all-zeros prefix in %s, line %d", filename, num_lines);
486-
487-
if (getifaddrs(&ifap) != 0)
488-
flog(LOG_ERR, "getifaddrs failed: %s", strerror(errno));
489-
490-
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
491-
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr;
492-
struct sockaddr_in6 *mask = (struct sockaddr_in6 *)ifa->ifa_netmask;
493-
char buf[INET6_ADDRSTRLEN];
494-
495-
if (strncmp(ifa->ifa_name, iface->props.name, IFNAMSIZ))
496-
continue;
497-
498-
if (ifa->ifa_addr->sa_family != AF_INET6)
499-
continue;
500-
501-
s6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
502-
503-
if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr))
504-
continue;
505-
506-
prefix = malloc(sizeof(struct AdvPrefix));
507-
508-
if (prefix == NULL) {
509-
flog(LOG_CRIT, "malloc failed: %s", strerror(errno));
510-
ABORT;
511-
}
512-
513-
prefix_init_defaults(prefix);
514-
prefix->Prefix = get_prefix6(&s6->sin6_addr, &mask->sin6_addr);
515-
prefix->AdvRouterAddr = 1;
516-
prefix->AutoSelected = 1;
517-
prefix->next = next;
518-
next = prefix;
519-
520-
if (prefix->PrefixLen == 0)
521-
prefix->PrefixLen = count_mask(mask);
522-
523-
if (inet_ntop(ifa->ifa_addr->sa_family, (void *)&(prefix->Prefix), buf, sizeof(buf)) == NULL)
524-
flog(LOG_ERR, "%s: inet_ntop failed in %s, line %d!", ifa->ifa_name, filename, num_lines);
525-
else
526-
dlog(LOG_DEBUG, 3, "auto-selected prefix %s/%d on interface %s", buf, prefix->PrefixLen, ifa->ifa_name);
527-
}
528-
529-
if (!prefix) {
530-
flog(LOG_WARNING, "no auto-selected prefix on interface %s, disabling advertisements", iface->props.name);
531-
}
532-
533-
if (ifap)
534-
freeifaddrs(ifap);
535-
#endif /* ifndef HAVE_IFADDRS_H */
394+
flog(LOG_WARNING, "invalid all-zeros prefix in %s, line %d", filename, num_lines);
536395
}
537-
else {
538-
prefix = malloc(sizeof(struct AdvPrefix));
396+
prefix = malloc(sizeof(struct AdvPrefix));
539397

540-
if (prefix == NULL) {
541-
flog(LOG_CRIT, "malloc failed: %s", strerror(errno));
542-
ABORT;
543-
}
398+
if (prefix == NULL) {
399+
flog(LOG_CRIT, "malloc failed: %s", strerror(errno));
400+
ABORT;
401+
}
544402

545-
prefix_init_defaults(prefix);
403+
prefix_init_defaults(prefix);
546404

547-
if ($4 > MAX_PrefixLen)
548-
{
549-
flog(LOG_ERR, "invalid prefix length in %s, line %d", filename, num_lines);
550-
ABORT;
551-
}
405+
if ($4 > MAX_PrefixLen)
406+
{
407+
flog(LOG_ERR, "invalid prefix length in %s, line %d", filename, num_lines);
408+
ABORT;
409+
}
552410

553-
prefix->PrefixLen = $4;
411+
prefix->PrefixLen = $4;
554412

555-
memcpy(&prefix->Prefix, $2, sizeof(struct in6_addr));
556-
}
413+
memcpy(&prefix->Prefix, $2, sizeof(struct in6_addr));
557414
}
558415
;
559416

@@ -569,72 +426,33 @@ prefixplist : prefixplist prefixparms
569426
prefixparms : T_AdvOnLink SWITCH ';'
570427
{
571428
if (prefix) {
572-
if (prefix->AutoSelected) {
573-
struct AdvPrefix *p = prefix;
574-
do {
575-
p->AdvOnLinkFlag = $2;
576-
p = p->next;
577-
} while (p && p->AutoSelected);
578-
}
579-
else
580-
prefix->AdvOnLinkFlag = $2;
429+
prefix->AdvOnLinkFlag = $2;
581430
}
582431
}
583432
| T_AdvAutonomous SWITCH ';'
584433
{
585434
if (prefix) {
586-
if (prefix->AutoSelected) {
587-
struct AdvPrefix *p = prefix;
588-
do {
589-
p->AdvAutonomousFlag = $2;
590-
p = p->next;
591-
} while (p && p->AutoSelected);
592-
}
593-
else
594-
prefix->AdvAutonomousFlag = $2;
435+
prefix->AdvAutonomousFlag = $2;
595436
}
596437
}
597438
| T_AdvRouterAddr SWITCH ';'
598439
{
599440
if (prefix) {
600-
if (prefix->AutoSelected && $2 == 0)
601-
flog(LOG_WARNING, "prefix automatically selected, AdvRouterAddr always enabled, ignoring config line %d", num_lines);
602-
else
603-
prefix->AdvRouterAddr = $2;
441+
prefix->AdvRouterAddr = $2;
604442
}
605443
}
606444
| T_AdvValidLifetime number_or_infinity ';'
607445
{
608446
if (prefix) {
609-
if (prefix->AutoSelected) {
610-
struct AdvPrefix *p = prefix;
611-
do {
612-
p->AdvValidLifetime = $2;
613-
p->curr_validlft = $2;
614-
p = p->next;
615-
} while (p && p->AutoSelected);
616-
}
617-
else {
618-
prefix->AdvValidLifetime = $2;
619-
prefix->curr_validlft = $2;
620-
}
447+
prefix->AdvValidLifetime = $2;
448+
prefix->curr_validlft = $2;
621449
}
622450
}
623451
| T_AdvPreferredLifetime number_or_infinity ';'
624452
{
625453
if (prefix) {
626-
if (prefix->AutoSelected) {
627-
struct AdvPrefix *p = prefix;
628-
do {
629-
p->AdvPreferredLifetime = $2;
630-
p->curr_preferredlft = $2;
631-
p = p->next;
632-
} while (p && p->AutoSelected);
633-
}
634-
else {
635-
prefix->AdvPreferredLifetime = $2;
636-
prefix->curr_preferredlft = $2;
637-
}
454+
prefix->AdvPreferredLifetime = $2;
455+
prefix->curr_preferredlft = $2;
638456
}
639457
}
640458
| T_DeprecatePrefix SWITCH ';'
@@ -651,28 +469,30 @@ prefixparms : T_AdvOnLink SWITCH ';'
651469
}
652470
| T_Base6Interface name ';'
653471
{
472+
#ifndef HAVE_IFADDRS_H
473+
flog(LOG_ERR, "Base6Interface not supported in %s, line %d", filename, num_lines);
474+
ABORT;
475+
#else
654476
if (prefix) {
655-
if (prefix->AutoSelected) {
656-
flog(LOG_ERR, "automatically selecting the prefix and Base6Interface are mutually exclusive");
657-
ABORT;
658-
} /* fallthrough */
659477
dlog(LOG_DEBUG, 4, "using prefixes on interface %s for prefixes on interface %s", $2, iface->props.name);
660478
strncpy(prefix->if6, $2, IFNAMSIZ-1);
661479
prefix->if6[IFNAMSIZ-1] = '\0';
662480
}
481+
#endif
663482
}
664483

665484
| T_Base6to4Interface name ';'
666485
{
486+
#ifndef HAVE_IFADDRS_H
487+
flog(LOG_ERR, "Base6to4Interface not supported in %s, line %d", filename, num_lines);
488+
ABORT;
489+
#else
667490
if (prefix) {
668-
if (prefix->AutoSelected) {
669-
flog(LOG_ERR, "automatically selecting the prefix and Base6to4Interface are mutually exclusive");
670-
ABORT;
671-
} /* fallthrough */
672491
dlog(LOG_DEBUG, 4, "using interface %s for 6to4 prefixes on interface %s", $2, iface->props.name);
673492
strncpy(prefix->if6to4, $2, IFNAMSIZ-1);
674493
prefix->if6to4[IFNAMSIZ-1] = '\0';
675494
}
495+
#endif
676496
}
677497
;
678498

@@ -1036,41 +856,6 @@ number_or_infinity : NUMBER
1036856

1037857
%%
1038858

1039-
static int countbits(int b)
1040-
{
1041-
int count;
1042-
1043-
for (count = 0; b != 0; count++) {
1044-
b &= b - 1; // this clears the LSB-most set bit
1045-
}
1046-
1047-
return (count);
1048-
}
1049-
1050-
static int count_mask(struct sockaddr_in6 *m)
1051-
{
1052-
struct in6_addr *in6 = &m->sin6_addr;
1053-
int i;
1054-
int count = 0;
1055-
1056-
for (i = 0; i < 16; ++i) {
1057-
count += countbits(in6->s6_addr[i]);
1058-
}
1059-
return count;
1060-
}
1061-
1062-
static struct in6_addr get_prefix6(struct in6_addr const *addr, struct in6_addr const *mask)
1063-
{
1064-
struct in6_addr prefix = *addr;
1065-
int i = 0;
1066-
1067-
for (; i < 16; ++i) {
1068-
prefix.s6_addr[i] &= mask->s6_addr[i];
1069-
}
1070-
1071-
return prefix;
1072-
}
1073-
1074859
static void cleanup(void)
1075860
{
1076861
if (iface) {

interface.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ void prefix_init_defaults(struct AdvPrefix *prefix)
113113
prefix->AdvPreferredLifetime = DFLT_AdvPreferredLifetime;
114114
prefix->DeprecatePrefixFlag = DFLT_DeprecatePrefixFlag;
115115
prefix->DecrementLifetimesFlag = DFLT_DecrementLifetimesFlag;
116-
prefix->if6to4[0] = 0;
117-
prefix->enabled = 1;
118116

119117
prefix->curr_validlft = prefix->AdvValidLifetime;
120118
prefix->curr_preferredlft = prefix->AdvPreferredLifetime;

process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ static void process_ra(struct Interface *iface, unsigned char *msg, int len, str
255255
struct AdvPrefix *prefix = iface->AdvPrefixList;
256256
while (prefix) {
257257
char prefix_str[INET6_ADDRSTRLEN];
258-
if (prefix->enabled && (prefix->PrefixLen == pinfo->nd_opt_pi_prefix_len)
258+
if ((prefix->PrefixLen == pinfo->nd_opt_pi_prefix_len)
259259
&& addr_match(&prefix->Prefix, &pinfo->nd_opt_pi_prefix, prefix->PrefixLen)) {
260260
addrtostr(&prefix->Prefix, prefix_str, sizeof(prefix_str));
261261

0 commit comments

Comments
 (0)