Skip to content

Commit

Permalink
querierctl: Fix handling of bigger interface indexes in router port p…
Browse files Browse the repository at this point in the history
…arsing

Follow up to g97a532a

Keeping track of every possible interface index using a bitmap would
require many many bits on the stack. A better data structure would
possibly be a hashmap, but a pragmatic aproach at least for now is to
just sort the input before parsing, and since we are already fork a shell
we can just pipe to sort(1).

This patch introduces jq as a dependency. JSON is the only supported
machine friendly output format from iproute2 and jq is already available
on the current known targets of querierd.

Signed-off-by: Jacques de Laval <[email protected]>
  • Loading branch information
jackuess committed Jun 21, 2022
1 parent 67da7b9 commit 29e716c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 163 deletions.
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ querierd_SOURCES = main.c cfparse.y config.c defs.h \
igmp.c igmpv2.h igmpv3.h \
inet.c ipc.c kern.c log.c \
bridge.c pev.c pev.h \
pathnames.h queue.h bitstring.h
pathnames.h queue.h
querierd_CPPFLAGS = $(AM_CPPFLAGS)
querierd_LDADD = $(LIBS) $(LIBOBJS)

Expand Down
128 changes: 0 additions & 128 deletions src/bitstring.h

This file was deleted.

85 changes: 51 additions & 34 deletions src/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <string.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include "bitstring.h"
#include "defs.h"
#include "queue.h"

Expand Down Expand Up @@ -208,56 +207,74 @@ void bridge_prop(FILE *fp, char *prop, int setval)
fprintf(fp, "\n");
}

/*
* Parse output from bridge -s -json vlan global:
* > bridge -s -json vlan global show br0 | jq
* [
* {
* "ifname": "br0",
* "vlans": [
* {
* "vlan": 1,
* ...
* "router_ports": [
* {
* "port": "eth0",
* "timer": " 29.01",
* "type": "temp"
* }
* ]
* },
* {
* "vlan": 2,
* ...
* "router_ports": [
* {
* "port": "eth1",
* "timer": " 19.04",
* "type": "temp"
* }
* ]
* }
* ]
* }
* ]
*/
void bridge_router_ports(FILE *fp)
{
char cmd[80], buf[80];
FILE *rfp;
static const char *bridge_args = "-json -s vlan global show dev";
static const char *jq_filter = ".[].vlans[].router_ports[] | " \
".port + \" \" + .timer + \" \" + .type";
char prev_ifname[20] = { 0 };
char cmd[256], buf[80];
int num = 0;
int in_rport_context = 0;
FILE *rfp;
int ret;
bitstr_t bit_decl(seen, CHAR_BIT * sizeof(unsigned long));

ret = snprintf(cmd, sizeof(cmd), "bridge -s vlan global show dev %s", br);
ret = snprintf(cmd, sizeof(cmd), "bridge %s %s | jq -r '%s' | sort",
bridge_args, br, jq_filter);
if (ret < 0 || ret >= (int)sizeof(cmd))
goto fail;
rfp = popen(cmd, "r");
if (!rfp)
goto fail;

/*
* Parse output from bridge -s vlan global:
* > bridge -s vlan global show br0
* port vlan-id
* br0 1
* mcast_snooping 1 mcast_querier 1 ...
* router ports: eth2 0.00 temp
* eth1 29.01 temp
* 2
* mcast_snooping 1 mcast_querier 1 ...
* router ports: eth2 19.04 temp
*/
while (fgets(buf, sizeof(buf), rfp)) {
const char *fmt;
char ifname[20];
int seen = 0;
float timer;

if (in_rport_context)
fmt = " %19s %2f temp";
else
fmt = " router ports: %19s %2f temp";
if (sscanf(buf, "%19s %2f temp", ifname, &timer) != 2)
continue;

if (sscanf(buf, fmt, ifname, &timer) == 2) {
unsigned int ifi = if_nametoindex(ifname);
seen = prev_ifname[0] && !strncmp(ifname, prev_ifname, sizeof(ifname));

logit(LOG_DEBUG, 0, "Found router port %s (%lu) with %.2f s timeout\n", ifname, ifi, timer);
if (timer > 0.0 && ifi && !bit_test(seen, ifi)) {
fprintf(fp, "%s%s", num ? ", " : "", ifname);
num++;
bit_set(seen, ifi);
}
in_rport_context = 1;
} else
in_rport_context = 0;
logit(LOG_DEBUG, 0, "Found router port %s with %.2f s timeout\n", ifname, timer);
if (timer > 0.0 && !seen) {
fprintf(fp, "%s%s", num ? ", " : "", ifname);
num++;
memcpy(prev_ifname, ifname, sizeof(prev_ifname));
}
}
pclose(rfp);

Expand Down

0 comments on commit 29e716c

Please sign in to comment.