mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-05 20:48:07 +00:00

If get_rt_realms() fails, try to get a possible raw u32 realms value for the u32 RTA_FLOW/FRA_FLOW attribute, as it might be useful to directly configure the hex value itself. And only if that fails, then bail out. The source realm is provided in the upper u16 (mask: 0xffff0000) and the destination realm through the lower u16 part (mask: 0x0000ffff). This can be useful for tc's bpf realm matcher, but also a full hex/mask param can be provided already for matching through iptables' --realm cmdline option, for example. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
125 lines
2.5 KiB
C
125 lines
2.5 KiB
C
/*
|
|
* rtm_map.c
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*
|
|
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <syslog.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include "rt_names.h"
|
|
#include "utils.h"
|
|
|
|
char *rtnl_rtntype_n2a(int id, char *buf, int len)
|
|
{
|
|
switch (id) {
|
|
case RTN_UNSPEC:
|
|
return "none";
|
|
case RTN_UNICAST:
|
|
return "unicast";
|
|
case RTN_LOCAL:
|
|
return "local";
|
|
case RTN_BROADCAST:
|
|
return "broadcast";
|
|
case RTN_ANYCAST:
|
|
return "anycast";
|
|
case RTN_MULTICAST:
|
|
return "multicast";
|
|
case RTN_BLACKHOLE:
|
|
return "blackhole";
|
|
case RTN_UNREACHABLE:
|
|
return "unreachable";
|
|
case RTN_PROHIBIT:
|
|
return "prohibit";
|
|
case RTN_THROW:
|
|
return "throw";
|
|
case RTN_NAT:
|
|
return "nat";
|
|
case RTN_XRESOLVE:
|
|
return "xresolve";
|
|
default:
|
|
snprintf(buf, len, "%d", id);
|
|
return buf;
|
|
}
|
|
}
|
|
|
|
|
|
int rtnl_rtntype_a2n(int *id, char *arg)
|
|
{
|
|
char *end;
|
|
unsigned long res;
|
|
|
|
if (strcmp(arg, "local") == 0)
|
|
res = RTN_LOCAL;
|
|
else if (strcmp(arg, "nat") == 0)
|
|
res = RTN_NAT;
|
|
else if (matches(arg, "broadcast") == 0 ||
|
|
strcmp(arg, "brd") == 0)
|
|
res = RTN_BROADCAST;
|
|
else if (matches(arg, "anycast") == 0)
|
|
res = RTN_ANYCAST;
|
|
else if (matches(arg, "multicast") == 0)
|
|
res = RTN_MULTICAST;
|
|
else if (matches(arg, "prohibit") == 0)
|
|
res = RTN_PROHIBIT;
|
|
else if (matches(arg, "unreachable") == 0)
|
|
res = RTN_UNREACHABLE;
|
|
else if (matches(arg, "blackhole") == 0)
|
|
res = RTN_BLACKHOLE;
|
|
else if (matches(arg, "xresolve") == 0)
|
|
res = RTN_XRESOLVE;
|
|
else if (matches(arg, "unicast") == 0)
|
|
res = RTN_UNICAST;
|
|
else if (strcmp(arg, "throw") == 0)
|
|
res = RTN_THROW;
|
|
else {
|
|
res = strtoul(arg, &end, 0);
|
|
if (!end || end == arg || *end || res > 255)
|
|
return -1;
|
|
}
|
|
*id = res;
|
|
return 0;
|
|
}
|
|
|
|
static int get_rt_realms(__u32 *realms, char *arg)
|
|
{
|
|
__u32 realm = 0;
|
|
char *p = strchr(arg, '/');
|
|
|
|
*realms = 0;
|
|
if (p) {
|
|
*p = 0;
|
|
if (rtnl_rtrealm_a2n(realms, arg)) {
|
|
*p = '/';
|
|
return -1;
|
|
}
|
|
*realms <<= 16;
|
|
*p = '/';
|
|
arg = p+1;
|
|
}
|
|
if (*arg && rtnl_rtrealm_a2n(&realm, arg))
|
|
return -1;
|
|
*realms |= realm;
|
|
return 0;
|
|
}
|
|
|
|
int get_rt_realms_or_raw(__u32 *realms, char *arg)
|
|
{
|
|
if (!get_rt_realms(realms, arg))
|
|
return 0;
|
|
|
|
return get_unsigned(realms, arg, 0);
|
|
}
|