mirror of
https://github.com/xdp-project/BNG-router.git
synced 2024-05-06 15:54:53 +00:00
Reformatting option 82 circuit ID to include interface name (including
VLAN tags) in ASCII format. Because VLAN tags are converted to ASCII with use of modulo, interface name is generated from right to left, starting with inner VLAN and prepended with dash characters to ensure a final length of IF_NAMESIZE bytes (16), e.g.: ----ens6f0.83.20 We avoid null bytes in circuit ID to ensure compatibility with DHCP servers that interpret null as string terminator.
This commit is contained in:
@@ -10,7 +10,8 @@
|
||||
#define DHO_DHCP_AGENT_OPTIONS 82
|
||||
#define RAI_CIRCUIT_ID 1
|
||||
#define RAI_REMOTE_ID 2
|
||||
#define RAI_OPTION_LEN 2
|
||||
#define RAI_OPTION_LEN 40
|
||||
#define VLAN_ASCII_MAX 4 /* Max bytes needed to store VLAN in ASCII format */
|
||||
|
||||
#define DHCP_SERVER_PORT 67
|
||||
#define DHCP_CLIENT_PORT 68
|
||||
|
@@ -49,7 +49,7 @@ struct {
|
||||
__uint(max_entries, 16384);
|
||||
} client_vlans SEC(".maps");
|
||||
|
||||
/* Inserts DHCP option 82 into the received dhcp packet
|
||||
/* Inserts DHCP option 82 into the received DHCP packet
|
||||
* at the specified offset.
|
||||
*/
|
||||
static __always_inline int write_dhcp_option_82(void *ctx, int offset,
|
||||
@@ -57,14 +57,68 @@ static __always_inline int write_dhcp_option_82(void *ctx, int offset,
|
||||
struct dhcp_option_82 option;
|
||||
|
||||
option.t = DHO_DHCP_AGENT_OPTIONS;
|
||||
option.len = sizeof(struct sub_option) + sizeof(struct sub_option);
|
||||
option.len = sizeof (struct sub_option) + sizeof (struct sub_option);
|
||||
option.circuit_id.option_id = RAI_CIRCUIT_ID;
|
||||
option.circuit_id.len = IF_NAMESIZE;
|
||||
memcpy(option.circuit_id.val, dev, IF_NAMESIZE);
|
||||
//option.circuit_id.val = bpf_ntohs(vlans->id[0]);
|
||||
option.circuit_id.len = sizeof(option.circuit_id.val);
|
||||
|
||||
/* Reconstruct VLAN device name
|
||||
* Convert VLAN tags to ASCII from right to left, starting with
|
||||
* inner VLAN tag.
|
||||
* Device name is 16 characters long and prepended with dash, e.g.:
|
||||
* ----ens6f0.83.20
|
||||
* We avoid null bytes to ensure compatibility with DHCP servers that
|
||||
* interpret null as a string terminator.
|
||||
*/
|
||||
|
||||
char buf[IF_NAMESIZE];
|
||||
memset(buf, '-', sizeof (buf));
|
||||
|
||||
int c = VLAN_ASCII_MAX; /* We will need 4 bytes at most */
|
||||
int i = IF_NAMESIZE - 1;
|
||||
__u16 inner_vlan = vlans->id[1];
|
||||
__u16 outer_vlan = vlans->id[0];
|
||||
|
||||
for (c = VLAN_ASCII_MAX; c > 0; c--) {
|
||||
buf[i--] = (inner_vlan % 10) + '0';
|
||||
inner_vlan /= 10;
|
||||
if (inner_vlan == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buf[i--] = '.';
|
||||
|
||||
for (c = VLAN_ASCII_MAX; c > 0; c--) {
|
||||
buf[i--] = (outer_vlan % 10) + '0';
|
||||
outer_vlan /= 10;
|
||||
if (outer_vlan == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buf[i--] = '.';
|
||||
|
||||
for (c = IF_NAMESIZE - 1; c >= 0; c--) {
|
||||
|
||||
if (dev[c] != 0) {
|
||||
buf[i--] = dev[c];
|
||||
}
|
||||
|
||||
if (i < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(sizeof(option.circuit_id.val) == sizeof(buf)) {
|
||||
memcpy(option.circuit_id.val, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* Initialize remote ID */
|
||||
memset(option.remote_id.val, 0, sizeof(option.remote_id.val));
|
||||
option.remote_id.option_id = RAI_REMOTE_ID;
|
||||
option.remote_id.len = IF_NAMESIZE;
|
||||
//option.remote_id.val = bpf_ntohs(vlans->id[1]);
|
||||
option.remote_id.len = sizeof(option.remote_id.val);
|
||||
|
||||
return xdp_store_bytes(ctx, offset, &option, sizeof (option), 0);
|
||||
}
|
||||
@@ -282,13 +336,13 @@ int xdp_dhcp_relay(struct xdp_md *ctx) {
|
||||
|
||||
bpf_printk("Broadcast packet received, opcode %i, hops %i", dhcp->op, dhcp->hops);
|
||||
|
||||
// Set destination MAC
|
||||
/* Set destination MAC */
|
||||
memcpy(eth->h_dest, relay_hwaddr, ETH_ALEN);
|
||||
|
||||
// Set source MAC
|
||||
//memcpy(eth->h_source, relay_hwaddr, ETH_ALEN);
|
||||
|
||||
// Set GIADDR
|
||||
/* Set GIADDR */
|
||||
if (&dhcp->giaddr.s_addr + sizeof (relay_agent_ip) > data_end) {
|
||||
rc = XDP_ABORTED;
|
||||
goto out;
|
||||
|
@@ -95,6 +95,57 @@ int xdp_link_attach(int ifindex, __u32 xdp_flags, int prog_fd) {
|
||||
*/
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
/*char device[500] = "ens6f0np0";
|
||||
char o82[30] = { 0 };
|
||||
|
||||
int outer_vlan = 80;
|
||||
int inner_vlan = 25;
|
||||
|
||||
char str[30] = {0}; // large enough for an int even on 64-bit
|
||||
int i = 30;
|
||||
int c = 0;
|
||||
|
||||
for(c = 4; c > 0; c--) {
|
||||
str[i--] = (inner_vlan % 10) + '0';
|
||||
inner_vlan /= 10;
|
||||
if(inner_vlan == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str[i--] = '.';
|
||||
|
||||
for(c = 4; c > 0; c--) {
|
||||
str[i--] = (outer_vlan % 10) + '0';
|
||||
outer_vlan /= 10;
|
||||
if(outer_vlan == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str[i--] = '.';
|
||||
|
||||
int y;
|
||||
for(y = sizeof(device) - 1; y >= 0; y--) {
|
||||
if(device[y] != 0) {
|
||||
str[i] = device[y];
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
printf("i is %i\n", i);
|
||||
|
||||
memset(o82, 0, 30);
|
||||
memcpy(o82, str + i + 1, 30 - i);
|
||||
|
||||
printf("The number was: %s\n", str + i + 1);
|
||||
|
||||
printf("Option 82: %s\n", o82);
|
||||
|
||||
printf("Option 82 length was %i\n", 30 - i);
|
||||
|
||||
return 0;*/
|
||||
|
||||
char filename[256] = "dhcp_kern_xdp.o";
|
||||
int prog_fd, err;
|
||||
int opt;
|
||||
|
Reference in New Issue
Block a user