Commit 704470ca by Cédric Le Ninivin Committed by Julien Muchembled

ctl: add command to change the cost multiplier of a neighbour

To be pushed upstream.

Co-authored-by: Julien Muchembled <jm@nexedi.com>
1 parent 4d6df5cb
Pipeline #301 for 704470ca skipped in 0 seconds
......@@ -73,6 +73,70 @@ ctl_resize_buffer(struct ctl_buffer *buffer, size_t n)
}
static int
ctl_set_cost_multiplier(struct ctl_buffer *buffer, void *packet, size_t length)
{
struct {
uint8_t address[16];
uint32_t ifindex;
uint16_t cost_multiplier;
} __attribute__((packed)) *request = packet;
unsigned ifindex = ntohl(request->ifindex);
struct neighbour *neigh;
struct {
uint16_t type;
uint32_t length;
uint8_t unknown:1;
uint8_t changed:1;
} __attribute__((packed)) *response;
size_t end = buffer->end + sizeof *response;
if(ctl_resize_buffer(buffer, end))
return -1;
response = (void *)(buffer->data + buffer->end);
response->type = htons(CTL_MSG_SET_COST_MULTIPLIER);
response->length = htonl(sizeof *response - 6);
response->unknown = 1;
response->changed = 0;
FOR_ALL_NEIGHBOURS(neigh)
if(neigh->ifp->ifindex == ifindex &&
!memcmp(request->address, neigh->address, sizeof request->address)) {
struct babel_route *route;
struct route_stream *routes;
unsigned short cost_multiplier;
cost_multiplier = ntohs(request->cost_multiplier);
response->unknown = 0;
response->changed = neigh->cost_multiplier != cost_multiplier;
if(!cost_multiplier && response->changed) {
routes = route_stream(1);
if(!routes)
return -1;
while((route = route_stream_next(routes)))
if(route->neigh == neigh) {
response->changed = 0;
break;
}
route_stream_done(routes);
}
if(response->changed) {
routes = route_stream(0);
if(!routes)
return -1;
neigh->cost_multiplier = cost_multiplier;
while((route = route_stream_next(routes)))
if(route->neigh == neigh)
update_route_metric(route);
route_stream_done(routes);
}
break;
}
buffer->end = end;
return 0;
}
static int
ctl_dump_interface(struct ctl_buffer *buffer, struct interface *ifp)
{
size_t end = buffer->end + strlen(ifp->name) + 1 + 4;
......@@ -101,6 +165,7 @@ ctl_dump_neighbour(struct ctl_buffer *buffer, struct neighbour *neigh)
neigh_dump->rttcost = htonl(neighbour_rttcost(neigh));
neigh_dump->channel = htonl(neigh->ifp->channel);
neigh_dump->if_up = htons(if_up(neigh->ifp));
neigh_dump->cost_multiplier = htons(neigh->cost_multiplier);
buffer->end = end;
return 0;
}
......@@ -247,6 +312,9 @@ ctl_work(struct ctl *ctl)
case CTL_MSG_DUMP:
ret = ctl_dump(&ctl->buffer_out, p, length);
break;
case CTL_MSG_SET_COST_MULTIPLIER:
ret = ctl_set_cost_multiplier(&ctl->buffer_out, p, length);
break;
}
else if(length < CTL_MAX_SIZE)
return;
......
......@@ -28,6 +28,7 @@ THE SOFTWARE.
#define CTL_VERSION 1
#define CTL_MSG_DUMP 1
#define CTL_MSG_SET_COST_MULTIPLIER 2
#define CTL_DUMP_NONE 0
#define CTL_DUMP_INSTALLED 1
......@@ -50,6 +51,7 @@ struct ctl_dump_neighbour {
uint16_t rttcost;
int32_t channel;
uint16_t if_up;
uint16_t cost_multiplier;
} __attribute__((packed));
......
......@@ -103,6 +103,7 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
neigh->rtt = 0;
neigh->rtt_time = zero;
neigh->ifp = ifp;
neigh->cost_multiplier = 256;
neigh->next = neighs;
neighs = neigh;
local_notify_neighbour(neigh, LOCAL_ADD);
......@@ -358,6 +359,10 @@ neighbour_cost(struct neighbour *neigh)
cost += neighbour_rttcost(neigh);
if(!neigh->cost_multiplier)
return INFINITY;
cost = cost * neigh->cost_multiplier >> 8 ?: 1;
return MIN(cost, INFINITY);
}
......
......@@ -39,6 +39,7 @@ struct neighbour {
unsigned int rtt;
struct timeval rtt_time;
struct interface *ifp;
unsigned short cost_multiplier;
};
extern struct neighbour *neighs;
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!