nft.c revision 7244bef43f350ab31ef54db8a81905f6c68acac0
1384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* 2384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org> 3384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * 4384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * This program is free software; you can redistribute it and/or modify 5384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * it under the terms of the GNU General Public License as published 6384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * by the Free Software Foundation; either version 2 of the License, or 7384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * (at your option) any later version. 8384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * 9384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * This code has been sponsored by Sophos Astaro <http://www.sophos.com> 10384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 11384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 12384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <unistd.h> 13384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <fcntl.h> 14384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <sys/types.h> 15384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <sys/socket.h> 16384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <stdbool.h> 17384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <errno.h> 18384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <netdb.h> /* getprotobynumber */ 19384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <time.h> 208b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso#include <stdarg.h> 210a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo#include <inttypes.h> 22384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 23384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <xtables.h> 24384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libiptc/libxtc.h> 25384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libiptc/xtcshared.h> 26384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 27384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <stdlib.h> 28384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <string.h> 29384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 30384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/x_tables.h> 310391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka#include <linux/netfilter_ipv4/ip_tables.h> 320391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka#include <linux/netfilter_ipv6/ip6_tables.h> 330391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka#include <netinet/ip6.h> 34384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 35384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netlink.h> 36384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/nfnetlink.h> 37384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/nf_tables.h> 38384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <linux/netfilter/nf_tables_compat.h> 39384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 40384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libmnl/libmnl.h> 41384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/table.h> 42384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/chain.h> 43384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/rule.h> 44384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <libnftables/expr.h> 45384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 46384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <netinet/in.h> /* inet_ntoa */ 47384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <arpa/inet.h> 48384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 49384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "nft.h" 50384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "xshared.h" /* proto_to_name */ 51077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include "nft-shared.h" 528b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso#include "xtables-config-parser.h" 53384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 54384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void *nft_fn; 55384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 56384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh, 57384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int (*cb)(const struct nlmsghdr *nlh, void *data), 58384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *data) 59384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 60384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 61384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 62384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 63384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_sendto(h->nl, nlh, nlh->nlmsg_len) < 0) { 64384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_send"); 65384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 66384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 67384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 68384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 69384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (ret > 0) { 70384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_cb_run(buf, ret, h->seq, h->portid, cb, data); 71384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret <= 0) 72384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 73384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 74384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 75384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 76384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 77384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 78384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 79384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 80384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 81384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 82384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 83384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define FILTER 0 84384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define MANGLE 1 85384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define RAW 2 86384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#define SECURITY 3 87890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso#define NAT 4 88890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso#define TABLES_MAX 5 89384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 90e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusostruct builtin_chain { 91e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso const char *name; 92890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso const char *type; 935b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso uint32_t prio; 94e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso uint32_t hook; 95e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso}; 96e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 97c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct builtin_table { 98384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 99e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso struct builtin_chain chains[NF_INET_NUMHOOKS]; 100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} tables[TABLES_MAX] = { 101384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [RAW] = { 102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "raw", 103e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 104e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 105e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 106890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1075b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -300, /* NF_IP_PRI_RAW */ 108e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 109e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 110e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 111e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 112890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1135b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -300, /* NF_IP_PRI_RAW */ 114e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 115e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 116e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 117384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [MANGLE] = { 119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "mangle", 120e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 121e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 122e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 123890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1245b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 125e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 126e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 127e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 128e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 129890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1305b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 131e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 132e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 133e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 134e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 135890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1365b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 137e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 138e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 139e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 140e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 141890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "route", 1425b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 143e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 144e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 145e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 146e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "POSTROUTING", 147890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1485b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 149e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_POST_ROUTING, 150e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 151e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 152384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 153384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [FILTER] = { 154384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "filter", 155e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 156e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 157e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 158890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1595b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 160e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 161e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 162e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 163e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 164890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1655b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 166e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 167e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 168e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 169e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 170890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1715b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 172e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 173e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 174e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [SECURITY] = { 177384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "security", 178e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 179e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 180e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 181890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1825b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 183e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 184e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 185e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 186e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 187890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1885b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 189e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 190e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 191e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 192e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 193890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 1945b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 195e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 196e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 197384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 198384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 199890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso [NAT] = { 200890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "nat", 201890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .chains = { 202890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 203890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "OUTPUT", 204890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 205890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = -100, /* NF_IP_PRI_NAT_DST */ 206890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 207890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 208890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 209890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "INPUT", 210890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 211890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = 100, /* NF_IP_PRI_NAT_SRC */ 212890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 213890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 214890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 215890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "PREROUTING", 216890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 217890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = -100, /* NF_IP_PRI_NAT_DST */ 218890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 219890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 220890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 221890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "POSTROUTING", 222890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 223890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = 100, /* NF_IP_PRI_NAT_SRC */ 224890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_POST_ROUTING, 225890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 226890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 227890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 229384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2305705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusostatic int 2315705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusonft_table_builtin_add(struct nft_handle *h, struct builtin_table *_t, 2325705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso bool dormant) 2335b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso{ 2345b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 2355b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso struct nlmsghdr *nlh; 2365b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso struct nft_table *t; 2375b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso int ret; 2385b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 2395b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso t = nft_table_alloc(); 2405b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso if (t == NULL) 2415b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso return -1; 2425b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 2435b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)_t->name); 2445705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (dormant) { 2455705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, 2465705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso NFT_TABLE_F_DORMANT); 2475705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso } 2485b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 2490391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family, 2505b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 2515b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 2525b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_table_free(t); 2535b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 2545b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 2555b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso if (ret < 0) { 2565b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso if (errno != EEXIST) 2575b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso perror("mnl-talk:nft_table_init_one"); 2585b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso } 2595b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso return ret; 2605b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso} 2615b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 262c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct nft_chain * 263c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_alloc(struct builtin_table *table, 264c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *chain, int policy) 265384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 266384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 267384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 269384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) 270c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return NULL; 271384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 272384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table->name); 273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain->name); 274384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_HOOKNUM, chain->hook); 2755b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_PRIO, chain->prio); 276384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy); 277890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TYPE, (char *)chain->type); 278384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 279c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return c; 280c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 281c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 282c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic void 283c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_add(struct nft_handle *h, struct builtin_table *table, 284c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *chain, int policy) 285c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 286c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 287c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct nlmsghdr *nlh; 288c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct nft_chain *c; 289c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 290c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_builtin_alloc(table, chain, policy); 291c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 292c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return; 293c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 294890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso /* NLM_F_CREATE requests module autoloading */ 2950391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 296890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE, 297890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso h->seq); 298384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 299384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 301384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_talk(h, nlh, NULL, NULL) < 0) { 302384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 303c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso perror("mnl_talk:nft_chain_builtin_add"); 304c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 305c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 306c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 307c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in table already exists */ 308c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct builtin_table *nft_table_builtin_find(const char *table) 309c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 310c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int i; 311c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 312c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 313c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso for (i=0; i<TABLES_MAX; i++) { 314c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (strcmp(tables[i].name, table) != 0) 315c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso continue; 316c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 317c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso found = true; 318c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso break; 319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 320c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 321c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return found ? &tables[i] : NULL; 322384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 324c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in chain already exists */ 325c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic struct builtin_chain * 326e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusonft_chain_builtin_find(struct builtin_table *t, const char *chain) 327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 328e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int i; 329c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 331e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && t->chains[i].name != NULL; i++) { 332e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (strcmp(t->chains[i].name, chain) != 0) 333e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso continue; 334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 335e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso found = true; 336e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso break; 337e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso } 338e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso return found ? &t->chains[i] : NULL; 339e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso} 340e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 341e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusostatic void 342e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso__nft_chain_builtin_init(struct nft_handle *h, 343e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso struct builtin_table *table, const char *chain, 344e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int policy) 345e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso{ 346e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int i, default_policy; 347e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 348e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* Initialize all built-in chains. Exception, for e one received as 349e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso * parameter, set the default policy as requested. 350e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso */ 351e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && table->chains[i].name != NULL; i++) { 352e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (chain && strcmp(table->chains[i].name, chain) == 0) 353e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy = policy; 354e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso else 355e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy = NF_ACCEPT; 356e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 357e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso nft_chain_builtin_add(h, table, &table->chains[i], 358e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy); 359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 360c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 361c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 362c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusostatic int 363c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_init(struct nft_handle *h, const char *table, 364c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso const char *chain, int policy) 365c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 366c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int ret = 0; 367c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *t; 368c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 369c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso t = nft_table_builtin_find(table); 370c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (t == NULL) { 371c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso ret = -1; 372c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso goto out; 373c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 3745705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (nft_table_builtin_add(h, t, false) < 0) { 375e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* Built-in table already initialized, skip. */ 376e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (errno == EEXIST) 377e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso goto out; 378c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 379e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso __nft_chain_builtin_init(h, t, chain, policy); 380c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusoout: 381c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return ret; 382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 3847244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztykastatic bool nft_chain_builtin(struct nft_chain *c) 3857244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka{ 3867244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka /* Check if this chain has hook number, in that case is built-in. 3877244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka * Should we better export the flags to user-space via nf_tables? 3887244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka */ 3897244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka return nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM) != NULL; 3907244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka} 3917244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka 392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_init(struct nft_handle *h) 393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 394384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->nl = mnl_socket_open(NETLINK_NETFILTER); 395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (h->nl == NULL) { 396384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_open"); 397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 399384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0) { 401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_bind"); 402384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 403384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 404384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->portid = mnl_socket_get_portid(h->nl); 405384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 406384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 407384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 408384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 409384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusovoid nft_fini(struct nft_handle *h) 410384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 411384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(h->nl); 412384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 413384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 414384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_table_add(struct nft_handle *h, const struct nft_table *t) 415384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 416384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 417384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 4190391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family, 420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 424384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 426384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_add(struct nft_handle *h, const struct nft_chain *c) 427384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 428384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 429384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 430384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 4310391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 432384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 433384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 434384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 435384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 436384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 437384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 4385705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusoint nft_table_set_dormant(struct nft_handle *h, const char *table) 4395705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso{ 4405705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso int ret = 0, i; 4415705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso struct builtin_table *t; 4425705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 4435705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso t = nft_table_builtin_find(table); 4445705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (t == NULL) { 4455705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso ret = -1; 4465705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso goto out; 4475705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso } 4485705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso /* Add this table as dormant */ 4495705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (nft_table_builtin_add(h, t, true) < 0) { 4505705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso /* Built-in table already initialized, skip. */ 4515705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (errno == EEXIST) 4525705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso goto out; 4535705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso } 4545705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso for (i=0; t->chains[i].name != NULL && i<NF_INET_NUMHOOKS; i++) 4555705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso __nft_chain_builtin_init(h, t, t->chains[i].name, NF_ACCEPT); 4565705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusoout: 4575705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso return ret; 4585705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso} 4595705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 4605705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusoint nft_table_wake_dormant(struct nft_handle *h, const char *table) 4615705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso{ 4625705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 4635705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso struct nlmsghdr *nlh; 4645705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso struct nft_table *t; 4655705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 4665705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso t = nft_table_alloc(); 4675705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (t == NULL) 4685705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso return -1; 4695705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 4705705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)table); 4715705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, 0); 4725705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 4730391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family, 4745705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso NLM_F_ACK, h->seq); 4755705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 4765705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_free(t); 4775705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 4785705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 4795705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso} 4805705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_chain_print_debug(struct nft_chain *c, struct nlmsghdr *nlh) 482384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 483384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 485384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0); 487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("DEBUG: chain: %s", tmp); 488384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 490384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 492384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_chain_set(struct nft_handle *h, const char *table, 494384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain, int policy, 495384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters) 496384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 497384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 498384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 499384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 500c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *_t; 501c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *_c; 502e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int ret; 503c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 504c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso _t = nft_table_builtin_find(table); 505c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* if this built-in table does not exists, create it */ 506c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_t != NULL) 5075705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_builtin_add(h, _t, false); 508c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 509e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso _c = nft_chain_builtin_find(_t, chain); 510c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_c != NULL) { 511c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* This is a built-in chain */ 512c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_builtin_alloc(_t, _c, policy); 513c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 514c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return -1; 515c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } else { 51620c156f9f4c43857a622f015a3022517601c3600Tomasz Bursztyka errno = ENOENT; 51720c156f9f4c43857a622f015a3022517601c3600Tomasz Bursztyka return -1; 518c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 520384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 521384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, 522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->bcnt); 523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, 524384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->pcnt); 525384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 5270391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 530384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_print_debug(c, nlh); 532384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 533384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 534384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 535384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 536384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 537384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_chain_policy"); 538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 539384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 540384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_set(struct nft_handle *h, const char *table, 543384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain, const char *policy, 544384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters) 545384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = -1; 547384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 548384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_chain_set; 549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 550384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(policy, "DROP") == 0) 551384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_set(h, table, chain, NF_DROP, counters); 552384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(policy, "ACCEPT") == 0) 553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_set(h, table, chain, NF_ACCEPT, counters); 554384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 555384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 556384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 557384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 558384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 559f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int __add_match(struct nft_rule_expr *e, struct xt_entry_match *m) 560384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 561384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *info; 562384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 563384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_MT_NAME, m->u.user.name, strlen(m->u.user.name)); 564384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(e, NFT_EXPR_MT_REV, m->u.user.revision); 565384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 566384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso info = calloc(1, m->u.match_size); 567384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) 568f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 569384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 570384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(info, m->data, m->u.match_size); 571384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_MT_INFO, info, m->u.match_size - sizeof(*m)); 572f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 573f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 574384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 575384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 576f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int add_match(struct nft_rule *r, struct xt_entry_match *m) 577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 579f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka int ret; 580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("match"); 582384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 583f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 584384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 585f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = __add_match(expr, m); 586384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 587f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 588f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return ret; 589384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 591f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int __add_target(struct nft_rule_expr *e, struct xt_entry_target *t) 592384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 593384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *info = NULL; 594384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 595384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_TG_NAME, t->u.user.name, 596384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strlen(t->u.user.name)); 597384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(e, NFT_EXPR_TG_REV, t->u.user.revision); 598384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 599384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) { 600384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso info = calloc(1, t->u.target_size); 601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) 602f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 603384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 604384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(info, t->data, t->u.target_size); 605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 606384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 607384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_TG_INFO, info, t->u.target_size - sizeof(*t)); 608f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 609f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 610384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 611384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 612f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int add_target(struct nft_rule *r, struct xt_entry_target *t) 613384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 614384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 615f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka int ret; 616384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 617384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("target"); 618384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 619f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 620384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 621f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = __add_target(expr, t); 622384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 623f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 624f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return ret; 625384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 626384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 627f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int add_jumpto(struct nft_rule *r, const char *name, int verdict) 628384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 629384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 630384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 631384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("immediate"); 632384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 633f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 634384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 635384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT); 636384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict); 637384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_str(expr, NFT_EXPR_IMM_CHAIN, (char *)name); 638384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 639f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 640f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 641384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 642384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 643f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int add_verdict(struct nft_rule *r, int verdict) 644384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 645384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 646384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 647384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("immediate"); 648384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 649f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 650384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 651384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT); 652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict); 653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 654f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 655f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 656384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 657384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 658384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_rule_print_debug(struct nft_rule *r, struct nlmsghdr *nlh) 659384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 660384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 661384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 662384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 663384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0); 664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("DEBUG: rule: %s", tmp); 665384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 666384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 667384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 668384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 669f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int add_counters(struct nft_rule *r, uint64_t packets, uint64_t bytes) 670384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 671384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 672384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 673384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("counter"); 674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 675f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 676384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_BYTES, packets); 678384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_PACKETS, bytes); 679384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 680384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 681f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 682f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 683384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 684384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 6854ef77b6d1b52e1fe52a7fd48d38d9233f0961640Pablo Neira Ayusovoid add_compat(struct nft_rule *r, uint32_t proto, bool inv) 6862a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso{ 6872a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_PROTO, proto); 6882a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_FLAGS, 6892a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso inv ? NFT_RULE_COMPAT_F_INV : 0); 6902a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso} 6912a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso 692384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint 693384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_rule_add(struct nft_handle *h, const char *chain, const char *table, 6940a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka struct iptables_command_state *cs, 6951298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso bool append, uint64_t handle, bool verbose) 696384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xtables_rule_match *matchp; 700384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 1; 702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int flags = append ? NLM_F_APPEND : 0; 7030391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka int ip_flags = 0; 704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 705e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 7068b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 7078b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso nft_chain_builtin_init(h, table, chain, NF_ACCEPT); 708c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_add; 710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) { 713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 716384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 717d370c4ad803c37eedfbee5963fac6f7e9968939cTomasz Bursztyka nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, h->family); 718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table); 719384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain); 720384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 721077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka ip_flags = h->ops->add(r, cs); 722384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 723f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka for (matchp = cs->matches; matchp; matchp = matchp->next) { 724f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka if (add_match(r, matchp->match->m) < 0) { 725f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = 0; 726f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka goto err; 727f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka } 728f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka } 729384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 730384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Counters need to me added before the target, otherwise they are 731384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * increased for each rule because of the way nf_tables works. 732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 733f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka if (add_counters(r, cs->counters.pcnt, cs->counters.bcnt) < 0) { 734f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = 0; 735f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka goto err; 736f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka } 737384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 738384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* If no target at all, add nothing (default to continue) */ 739384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (cs->target != NULL) { 740384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target? */ 741384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0) 742f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = add_verdict(r, NF_ACCEPT); 743384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0) 744f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = add_verdict(r, NF_DROP); 745384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0) 746f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = add_verdict(r, NFT_RETURN); 747384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 748f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = add_target(r, cs->target->t); 749384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strlen(cs->jumpto) > 0) { 750384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Not standard, then it's a go / jump to chain */ 7510391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka if (ip_flags & IPT_F_GOTO) 752f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = add_jumpto(r, cs->jumpto, NFT_GOTO); 753384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 754f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = add_jumpto(r, cs->jumpto, NFT_JUMP); 755f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka } 756f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 757f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka if (ret < 0) { 758f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = 0; 759f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka goto err; 760384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 761384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 762384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* NLM_F_CREATE autoloads the built-in table if it does not exists */ 7630a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka flags |= NLM_F_ACK|NLM_F_CREATE; 7640a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka 7650a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka if (handle > 0) { 7660a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka nft_rule_attr_set(r, NFT_RULE_ATTR_HANDLE, &handle); 7670a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka flags |= NLM_F_REPLACE; 7680a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka } 7690a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka 7709e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso if (h->commit) { 7719e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS, 7729e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso NFT_RULE_F_COMMIT); 7739e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 7740a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, 7750391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka h->family, flags, h->seq); 7760a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka 777384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_nlmsg_build_payload(nlh, r); 778384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 779384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_print_debug(r, nlh); 780384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 781384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_free(r); 782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 783384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 784384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 785384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_rule_add"); 786384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 787384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 788384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 789384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 790384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 791384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 792384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_match_save(struct nft_rule_expr *expr) 793384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 794384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 795384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_match *match; 796384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_match *emu; 797384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *mtinfo; 798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 799384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 800384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME); 801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 802384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso match = xtables_find_match(name, XTF_TRY_LOAD, NULL); 803384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match == NULL) 804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 806384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mtinfo = nft_rule_expr_get(expr, NFT_EXPR_MT_INFO, &len); 807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mtinfo == NULL) 808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 810384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso emu = calloc(1, sizeof(struct xt_entry_match) + len); 811384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (emu == NULL) 812384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 813384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 814384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(&emu->data, mtinfo, len); 815384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 816384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match->alias) 817384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-m %s", match->alias(emu)); 818384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 819384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-m %s", match->name); 820384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 821384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing parameter */ 822c51b85f995caebd41e6d063c8bcab513b305bcaaPablo Neira Ayuso if (match->save) 823c51b85f995caebd41e6d063c8bcab513b305bcaaPablo Neira Ayuso match->save(NULL, emu); 824384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 825384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" "); 826384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 827384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(emu); 828384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 829384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 830384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_target_save(struct nft_rule_expr *expr) 831384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 832384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 833384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_target *target; 834384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_target *emu; 835384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *tginfo; 836384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 837384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(expr, NFT_EXPR_TG_NAME); 839384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target not supported, we use native immediate expression */ 841384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "") == 0) { 842384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("ERROR: standard target seen, should not happen\n"); 843384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 844384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 845384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 846384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target = xtables_find_target(name, XTF_TRY_LOAD); 847384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target == NULL) 848384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 850384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso tginfo = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, &len); 851384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (tginfo == NULL) 852384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 853384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 854384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso emu = calloc(1, sizeof(struct xt_entry_match) + len); 855384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (emu == NULL) 856384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 857384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 858384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(emu->data, tginfo, len); 859384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 860384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target->alias) 861384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j %s", target->alias(emu)); 862384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 863384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j %s", target->name); 864384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 865384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing parameter */ 866c51b85f995caebd41e6d063c8bcab513b305bcaaPablo Neira Ayuso if (target->save) 867c51b85f995caebd41e6d063c8bcab513b305bcaaPablo Neira Ayuso target->save(NULL, emu); 868384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 869384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(emu); 870384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 871384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 872384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_immediate_save(struct nft_rule_expr *expr) 873384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t verdict; 875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 876384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict = nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT); 877384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 878384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 879384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 880384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j ACCEPT"); 881384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 882384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 883384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j DROP"); 884384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 885384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 886384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j RETURN"); 887384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 888384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_GOTO: 889384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-g %s", 890384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN)); 891384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 892384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_JUMP: 893384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-j %s", 894384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN)); 895384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 896384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 897384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 898384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 899384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 900384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_print_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter) 901384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 902384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t key = nft_rule_expr_get_u8(e, NFT_EXPR_META_KEY); 903384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t value; 904384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 905384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char ifname[IFNAMSIZ]; 906384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *ifname_ptr; 907384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 908384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 909384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso e = nft_rule_expr_iter_next(iter); 910384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (e == NULL) 911384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 912384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 913384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME); 914384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* meta should be followed by cmp */ 915384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "cmp") != 0) { 916384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("skipping no cmp after meta\n"); 917384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 918384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 919384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 920384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(key) { 921384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_IIF: 922384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA); 923384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if_indextoname(value, ifname); 924384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 925384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 926384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 927384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-i %s ", ifname); 928384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 929384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 930384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -i %s ", ifname); 931384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 932384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 933384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 934384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_OIF: 935384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA); 936384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if_indextoname(value, ifname); 937384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 938384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 939384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 940384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-o %s ", ifname); 941384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 942384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 943384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -o %s ", ifname); 944384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 945384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 946384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 947384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_IIFNAME: 948384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname_ptr = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len); 949384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(ifname, ifname_ptr, len); 950384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '\0'; 951384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 952384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* if this is zero, then assume this is a interface mask */ 953384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (if_nametoindex(ifname) == 0) { 954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '+'; 955384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len+1] = '\0'; 956384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 957384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 958384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 959384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 960384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-i %s ", ifname); 961384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 962384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 963384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -i %s ", ifname); 964384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 965384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 966384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 967384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_META_OIFNAME: 968384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname_ptr = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len); 969384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy(ifname, ifname_ptr, len); 970384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '\0'; 971384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 972384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* if this is zero, then assume this is a interface mask */ 973384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (if_nametoindex(ifname) == 0) { 974384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len] = '+'; 975384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ifname[len+1] = '\0'; 976384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 977384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 978384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) { 979384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_EQ: 980384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-o %s ", ifname); 981384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 982384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_CMP_NEQ: 983384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("! -o %s ", ifname); 984384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 985384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 986384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 987384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso default: 988384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("unknown meta key %d\n", key); 989384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 990384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 991384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 992384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 993384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 994384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_print_counters(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 995384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool counters) 996384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 997384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 9980a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf("-c %"PRIu64" %"PRIu64" ", 999384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS), 1000384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES)); 1001384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1002384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1003384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 10041ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayusovoid 10051ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayusonft_rule_print_save(struct nft_rule *r, enum nft_rule_print type, bool counters) 1006384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1007384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1008384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 10091ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso const char *chain = nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 1010384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1011384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 10121ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso switch(type) { 10131ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso case NFT_RULE_APPEND: 10141ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso printf("-A %s ", chain); 10151ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso break; 10161ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso case NFT_RULE_DEL: 10171ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso printf("-D %s ", chain); 10181ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso break; 10191ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso } 1020384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1021384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1022384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) 1023384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1024384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1025384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1026384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1027384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1028384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1029384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1030384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "counter") == 0) { 1031384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_print_counters(expr, iter, counters); 1032384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "payload") == 0) { 1033077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka struct nft_family_ops *ops = nft_family_ops_lookup( 1034077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY)); 1035077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka ops->print_payload(expr, iter); 1036384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "meta") == 0) { 1037384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_print_meta(expr, iter); 1038384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "match") == 0) { 1039384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_match_save(expr); 1040384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "target") == 0) { 1041384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_target_save(expr); 1042384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "immediate") == 0) { 1043384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_immediate_save(expr); 1044384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1045384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1046384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1047384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1048384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1049384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 1050384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1051384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1052384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_chain_list_cb(const struct nlmsghdr *nlh, void *data) 1053384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1054384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1055384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list = data; 1056384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1057384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 1058384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) { 1059384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1060384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1061384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1062384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1063384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_nlmsg_parse(nlh, c) < 0) { 1064384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1065384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1066384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1067384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1068384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_add(c, list); 1069384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1070384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1071384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1072384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 1073384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1074384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1075384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1076384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1077384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_chain_list *nft_chain_list_get(struct nft_handle *h) 1078384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1079384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1080384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1081384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1082384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1083384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1084384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_alloc(); 1085384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1086b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso errno = ENOMEM; 1087b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return NULL; 1088384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1089384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 10900391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, 1091384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1092384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1093384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_chain_list_cb, list); 1094384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1095384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_chain_list_get"); 1096384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1097384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1098384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1099384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostruct nft_chain_list *nft_chain_dump(struct nft_handle *h) 1101384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return nft_chain_list_get(h); 1103384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1104384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1105384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic const char *policy_name[NF_ACCEPT+1] = { 1106384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_DROP] = "DROP", 1107384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_ACCEPT] = "ACCEPT", 1108384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 1109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_chain_print_save(struct nft_chain *c, bool basechain) 1111384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1112384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain = nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint64_t pkts = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS); 1114384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint64_t bytes = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES); 1115384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1116384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 1117384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (basechain) { 1118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t pol = NF_ACCEPT; 1119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1120384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* no default chain policy? don't crash, display accept */ 1121384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_POLICY)) 1122384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso pol = nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 1123384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11240a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(":%s %s [%"PRIu64":%"PRIu64"]\n", chain, policy_name[pol], 1125384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso pkts, bytes); 1126384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 11270a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(":%s - [%"PRIu64":%"PRIu64"]\n", chain, pkts, bytes); 1128384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1129384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1130384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_save(struct nft_handle *h, struct nft_chain_list *list, 1131384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table) 1132384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1133384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1134384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1135384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1136384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1137b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1138384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1139384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1140384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1141384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 1143384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1144384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 1145384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1146384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 1147384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1148384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11497244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka basechain = nft_chain_builtin(c); 1150384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_print_save(c, basechain); 1151384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1152384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1153384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1154384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1155d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_chain_list_iter_destroy(iter); 1156384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1157384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1158384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1159384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1160384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1161384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_rule_list_cb(const struct nlmsghdr *nlh, void *data) 1162384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1163384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1164384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list = data; 1165384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1166384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 1167384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) { 1168384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1169384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1170384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1171384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1172384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_rule_nlmsg_parse(nlh, r) < 0) { 1173384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1174384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1177384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_add(r, list); 1178384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1179384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1180384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1181384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_free(r); 1182137cc981906f356c971da6de13e777a419382ff4Giuseppe Longo nft_rule_list_free(list); 1183384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1184384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1185384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1186384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1187384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_rule_list *nft_rule_list_get(struct nft_handle *h) 1188384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1189384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1190384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1191384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 1192384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1193384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1194384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_alloc(); 1195b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1196384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1197384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11980391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family, 1199384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1200384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1201384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_rule_list_cb, list); 1202384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1203384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_rule_save"); 1204384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 1205384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return NULL; 1206384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1207384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1208384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1209384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1210384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_save(struct nft_handle *h, const char *table, bool counters) 1212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 1214384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list_iter *iter; 1215384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 1218b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1219384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1220384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1221384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 1222b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1223384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1224384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1225384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1226384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 1227384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 1228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 1229384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1230384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0) 1231384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1232384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 12331ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso nft_rule_print_save(r, NFT_RULE_APPEND, counters); 1234384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1235384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1236384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1237384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1238384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1239d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_rule_list_iter_destroy(iter); 1240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 1241384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1242384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1243384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1244384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1245384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1246384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1247384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain) 1248384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1249384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1250384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1251384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1252384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1253384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 1254384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) 1255384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1256384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1257384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table); 1258384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain); 1259384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 12609e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso if (h->commit) { 12619e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS, 12629e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso NFT_RULE_F_COMMIT); 12639e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 12649e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 1265384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete all rules in this table + chain */ 12660391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_DELRULE, h->family, 1267384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 1268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_nlmsg_build_payload(nlh, r); 1269384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_free(r); 1270384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1271384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_talk(h, nlh, NULL, NULL) < 0) { 1272384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 1273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_rule_flush"); 1274384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1275384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1276384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1277384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) 1278384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1279384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1280384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1281384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1282384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1283384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1284384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_flush; 1285384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1286384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_get(h); 1287384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1288384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1289384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1291384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1292384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1293b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1294b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 1295384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1296384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1297384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1298384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1299384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1301384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1302384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1303384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1304384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1305384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1306384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1307384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1308384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1309384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __nft_rule_flush(h, table_name, chain_name); 1310384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 131136ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 131236ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 1313384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1314384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1315384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1317d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_chain_list_iter_destroy(iter); 1318384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1320384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1321384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1322384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1325384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table) 1326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1328384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1329384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1332e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 13338b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 13348b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); 1335e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 1336384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 1337b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (c == NULL) 1338b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return 0; 1339384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1340384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table); 1341384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain); 1342384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 13430391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 1344384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 1345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 1346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 1347384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 1349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1350384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 1351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_chain_add"); 1352384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1354384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int __nft_chain_del(struct nft_handle *h, struct nft_chain *c) 1359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1361384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 13640391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_DELCHAIN, h->family, 1365384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 1366384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 1367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 1369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST && errno != ENOENT) 1371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_chain_del"); 1372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1375384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1376384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1377384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table) 1378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1380384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1381384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 1383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int deleted_ctr = 0; 1384384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1385384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_get(h); 1386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1387384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1388384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1389384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1390b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1391b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 1392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1394384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1396384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1399384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* don't delete built-in chain */ 1401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_builtin(c)) 1402384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1403384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1404384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1405384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1406384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1407384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1408384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1409384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1410384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_del(h, c); 1411384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1412384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1413384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1414384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso deleted_ctr++; 141536ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo 141636ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 141736ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 1418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1419384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1422d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_chain_list_iter_destroy(iter); 1423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1424384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1426384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* chain not found */ 1427384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0 && deleted_ctr == 0) 1428384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 1429384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1430384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1431384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1432384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1433384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14340aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusostruct nft_chain * 1435e127d223d01aaa0886c7f279110ac36651b9a057Tomasz Bursztykanft_chain_list_find(struct nft_chain_list *list, 14360aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso const char *table, const char *chain) 14379c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso{ 14389c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 14399c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso struct nft_chain *c; 14409c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14419c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1442b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 14439c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return NULL; 14449c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14459c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 14469c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso while (c != NULL) { 14479c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso const char *table_name = 14489c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 14499c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso const char *chain_name = 14509c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 14519c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14529c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 14539c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso goto next; 14549c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14559c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (strcmp(chain, chain_name) != 0) 14569c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso goto next; 14579c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14580aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_list_iter_destroy(iter); 14599c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return c; 14609c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayusonext: 14619c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 14629c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso } 14630aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_list_iter_destroy(iter); 14649c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return NULL; 14659c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso} 14669c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14670aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusostatic struct nft_chain * 14680aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusonft_chain_find(struct nft_handle *h, const char *table, const char *chain) 14690aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso{ 14700aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain_list *list; 14710aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 14720aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso list = nft_chain_list_get(h); 1473b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 14740aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return NULL; 14750aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1476e127d223d01aaa0886c7f279110ac36651b9a057Tomasz Bursztyka return nft_chain_list_find(list, table, chain); 14770aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso} 14780aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1479384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_rename(struct nft_handle *h,const char *chain, 1480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, const char *newname) 1481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 14824493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka char buf[MNL_SOCKET_BUFFER_SIZE]; 14834493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka struct nlmsghdr *nlh; 14844493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka struct nft_chain *c; 14859c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso uint64_t handle; 1486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14884493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka /* If built-in chains don't exist for this table, create them */ 14898b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 14908b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); 14914493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 14929c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso /* Find the old chain to be renamed */ 14939c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso c = nft_chain_find(h, table, chain); 14949c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (c == NULL) { 14959c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso errno = ENOENT; 14969c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return -1; 14979c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso } 14989c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso handle = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_HANDLE); 14999c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 15009c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso /* Now prepare the new name for the chain */ 15014493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka c = nft_chain_alloc(); 1502b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (c == NULL) 15034493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka return -1; 15044493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 15054493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table); 15069c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)newname); 15079c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_HANDLE, handle); 1508384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 15090391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 15109c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso NLM_F_ACK, h->seq); 15114493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka nft_chain_nlmsg_build_payload(nlh, c); 15124493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka nft_chain_free(c); 15134493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 15144493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka ret = mnl_talk(h, nlh, NULL, NULL); 15154493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka if (ret < 0) { 15164493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka if (errno != EEXIST) 15174493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka perror("mnl_talk:nft_chain_rename"); 15184493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka } 15194493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 15204493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka /* the core expects 1 for success and 0 for error */ 15214493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka return ret == 0 ? 1 : 0; 1522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1524384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_table_list_cb(const struct nlmsghdr *nlh, void *data) 1525384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1527384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list = data; 1528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_alloc(); 1530384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (t == NULL) { 1531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1532384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1533384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1534384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1535384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_table_nlmsg_parse(nlh, t) < 0) { 1536384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1537384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1539384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1540384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_add(t, list); 1541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1543384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1544384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_free(t); 1545384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1547384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1548384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_table_list *nft_table_list_get(struct nft_handle *h) 1550384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1551384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1552384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1554384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1555384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1556384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_alloc(); 1557b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1558384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1559384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 15600391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family, 1561384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1562384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1563384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_table_list_cb, list); 1564384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1565384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_table_list_get"); 1566384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1567384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1568384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1569384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1570384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusobool nft_table_find(struct nft_handle *h, const char *tablename) 1571384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1572384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1573384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list_iter *iter; 1574384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1575384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool ret = false; 1576384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_get(h); 1578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1579384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_table_list_iter_create(list); 1582b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1583384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1584384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1585384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1586384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1587384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *this_tablename = 1588384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_attr_get(t, NFT_TABLE_ATTR_NAME); 1589384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(tablename, this_tablename) == 0) 1591384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1592384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1593384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1594384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1595384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1596384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_free(list); 1597384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1598384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1599384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1600384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1602384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_for_each_table(struct nft_handle *h, 1603384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int (*func)(struct nft_handle *h, const char *tablename, bool counters), 1604384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool counters) 1605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1606384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 1; 1607384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1608384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list_iter *iter; 1609384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1610384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1611384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_get(h); 1612384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1613384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1614384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1615384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1616384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1617384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_table_list_iter_create(list); 1618b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1619384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1620384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1621384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1622384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1623384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *tablename = 1624384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_attr_get(t, NFT_TABLE_ATTR_NAME); 1625384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1626384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso func(h, tablename, counters); 1627384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1628384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1629384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1630384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1631384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_free(list); 1632384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1633384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1634384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1635384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1636384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1637384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 16380aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusoint nft_table_purge_chains(struct nft_handle *h, const char *this_table, 16390aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain_list *chain_list) 16400aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso{ 16410aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain_list_iter *iter; 16420aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain *chain_obj; 16430aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16440aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso iter = nft_chain_list_iter_create(chain_list); 1645b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 16460aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return 0; 16470aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16480aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso chain_obj = nft_chain_list_iter_next(iter); 16490aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso while (chain_obj != NULL) { 16500aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso const char *table = 16510aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_attr_get_str(chain_obj, NFT_CHAIN_ATTR_TABLE); 16520aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16530aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (strcmp(this_table, table) != 0) 16540aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso goto next; 16550aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16560aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (nft_chain_builtin(chain_obj)) 16570aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso goto next; 16580aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16590aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if ( __nft_chain_del(h, chain_obj) < 0) { 16600aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (errno != EBUSY) 16610aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return -1; 16620aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso } 16630aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusonext: 16640aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso chain_obj = nft_chain_list_iter_next(iter); 16650aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso } 16660aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_list_iter_destroy(iter); 16670aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16680aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return 0; 16690aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso} 16700aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1671384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic inline int 1672384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusomatch_different(const struct xt_entry_match *a, 1673384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const unsigned char *a_elems, 1674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const unsigned char *b_elems, 1675384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned char **maskptr) 1676384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_entry_match *b; 1678384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int i; 1679384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1680384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Offset of b is the same as a. */ 1681384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso b = (void *)b_elems + ((unsigned char *)a - a_elems); 1682384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1683384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (a->u.match_size != b->u.match_size) 1684384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1685384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1686384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(a->u.user.name, b->u.user.name) != 0) 1687384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1688384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1689384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso *maskptr += XT_ALIGN(sizeof(*a)); 1690384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1691384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (i = 0; i < a->u.match_size - XT_ALIGN(sizeof(*a)); i++) 1692384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (((a->data[i] ^ b->data[i]) & (*maskptr)[i]) != 0) 1693384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1694384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso *maskptr += i; 1695384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1696384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_parse_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 17000391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka int family, struct iptables_command_state *cs) 1701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint8_t key = nft_rule_expr_get_u8(e, NFT_EXPR_META_KEY); 1703077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka struct nft_family_ops *ops = nft_family_ops_lookup(family); 1704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name; 1705384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1706384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso e = nft_rule_expr_iter_next(iter); 1707384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (e == NULL) 1708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME); 1711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "cmp") != 0) { 1712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("skipping no cmp after meta\n"); 1713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1716077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka ops->parse_meta(e, key, cs); 17170391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka} 17180391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka 17190391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztykastatic void 17200391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztykanft_parse_payload(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 17210391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka int family, struct iptables_command_state *cs) 17220391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka{ 1723077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka struct nft_family_ops *ops = nft_family_ops_lookup(family); 17240391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka uint32_t offset; 17250391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka 17260391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET); 17270391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka 1728077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka ops->parse_payload(iter, cs, offset); 17290391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka} 17300391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka 17310391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztykastatic void 1732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_parse_counter(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 1733384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_counters *counters) 1734384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1735384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->pcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS); 1736384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->bcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES); 1737384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1738384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1739384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1740384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_parse_immediate(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter, 17410391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka int family, struct iptables_command_state *cs) 1742384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1743384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int verdict = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_VERDICT); 1744384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain = nft_rule_expr_get_str(e, NFT_EXPR_IMM_CHAIN); 1745077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka struct nft_family_ops *ops; 1746384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1747384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target? */ 1748384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 1749384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 1750384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = "ACCEPT"; 1751384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1752384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 1753384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = "DROP"; 1754384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1755384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 1756384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = "RETURN"; 1757384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1758384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_GOTO: 1759077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka ops = nft_family_ops_lookup(family); 1760077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka ops->parse_immediate(cs); 1761384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_JUMP: 1762384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso cs->jumpto = chain; 1763384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1764384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1765384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1766384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1767384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1768384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_rule_to_iptables_command_state(struct nft_rule *r, 1769384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state *cs) 1770384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1771384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1772384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 17730391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka int family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY); 1774384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1775384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1776384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (iter == NULL) 1777384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1778384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1779384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1780384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1781384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1783384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1784384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "counter") == 0) { 1785384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_parse_counter(expr, iter, &cs->counters); 1786384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "payload") == 0) { 17870391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nft_parse_payload(expr, iter, family, cs); 1788384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "meta") == 0) { 17890391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nft_parse_meta(expr, iter, family, cs); 1790384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "immediate") == 0) { 17910391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nft_parse_immediate(expr, iter, family, cs); 1792384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1793384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1794384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1795384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1796384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1797384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 1798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1799384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1800384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int matches_howmany(struct xtables_rule_match *matches) 1801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1802384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xtables_rule_match *matchp; 1803384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int matches_ctr = 0; 1804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (matchp = matches; matchp; matchp = matchp->next) 1806384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso matches_ctr++; 1807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return matches_ctr; 1809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1810384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1811384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool 1812384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__find_match(struct nft_rule_expr *expr, struct xtables_rule_match *matches) 1813384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1814384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *matchname = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME); 1815384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Netlink aligns this match info, don't trust this length variable */ 1816384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *data = nft_rule_expr_get_str(expr, NFT_EXPR_MT_INFO); 1817384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xtables_rule_match *matchp; 1818384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool found = false; 1819384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1820384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (matchp = matches; matchp; matchp = matchp->next) { 1821384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_match *m = matchp->match->m; 1822384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1823384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(m->u.user.name, matchname) != 0) { 1824384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("mismatching match name\n"); 1825384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso continue; 1826384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1827384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1828384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (memcmp(data, m->data, m->u.user.match_size - sizeof(*m)) != 0) { 1829384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("mismatch match data\n"); 1830384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso continue; 1831384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1832384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso found = true; 1833384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1834384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1835384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1836384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return found; 1837384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1839384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool find_matches(struct xtables_rule_match *matches, struct nft_rule *r) 1840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1841384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1842384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 1843384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int kernel_matches = 0; 1844384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1845384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1846b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1847384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1848384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1850384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1851384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1852384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1853384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1854384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "match") == 0) { 1855384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!__find_match(expr, matches)) 1856384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1857384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1858384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso kernel_matches++; 1859384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1860384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1861384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1862384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 1863384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1864384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* same number of matches? */ 1865384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (matches_howmany(matches) != kernel_matches) 1866384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1867384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1868384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1869384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1870384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1871384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool __find_target(struct nft_rule_expr *expr, struct xt_entry_target *t) 1872384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1873384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 1874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *tgname = nft_rule_expr_get_str(expr, NFT_EXPR_TG_NAME); 1875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Netlink aligns this target info, don't trust this length variable */ 1876384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *data = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, &len); 1877384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1878384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(t->u.user.name, tgname) != 0) { 1879384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("mismatching target name\n"); 1880384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1881384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1882384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1883384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (memcmp(data, t->data, t->u.user.target_size - sizeof(*t)) != 0) 1884384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1885384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1886384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1887384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1888384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1889384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int targets_howmany(struct xtables_target *target) 1890384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1891384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return target != NULL ? 1 : 0; 1892384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1893384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1894384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool 1895384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusofind_target(struct xtables_target *target, struct nft_rule *r) 1896384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1897384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1898384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 1899384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int kernel_targets = 0; 1900384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1901384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Special case: we use native immediate expressions to emulated 1902384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * standard targets. Also, we don't want to crash with no targets. 1903384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 1904384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target == NULL || strcmp(target->name, "standard") == 0) 1905384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1906384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1907384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1908b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1909384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1910384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1911384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1912384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1913384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1914384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1915384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1916384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "target") == 0) { 1917384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* we may support several targets in the future */ 1918384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!__find_target(expr, target->t)) 1919384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1920384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1921384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso kernel_targets++; 1922384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1923384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1924384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1925384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 1926384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1927384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* same number of targets? */ 1928384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (targets_howmany(target) != kernel_targets) { 1929384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("kernel targets is %d but we passed %d\n", 1930384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso kernel_targets, targets_howmany(target)); 1931384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1932384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1933384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1934384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1935384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1936384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1937384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic bool 1938384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusofind_immediate(struct nft_rule *r, const char *jumpto) 1939384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1940384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 1941384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 1942384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1943384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 1944b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1945384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1946384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1947384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1948384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 1949384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 1950384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 1951384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1952384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "immediate") == 0) { 1953384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int verdict = nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT); 1954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *verdict_name = NULL; 1955384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1956384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* No target specified but immediate shows up, this 1957384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso * is not the rule we are looking for. 1958384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso */ 1959384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strlen(jumpto) == 0) 1960384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1961384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1962384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 1963384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 1964384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict_name = "ACCEPT"; 1965384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1966384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 1967384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict_name = "DROP"; 1968384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1969384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 1970384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso verdict_name = "RETURN"; 1971384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1972384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1973384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1974384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Standard target? */ 1975384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (verdict_name && strcmp(jumpto, verdict_name) != 0) 1976384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return false; 1977384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1978384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 1979384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1980384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 1981384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1982384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1983384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1984384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1985384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1986384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_del(struct nft_handle *h, struct nft_rule *r) 1987384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1988384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1989384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1990384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1991384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 19920391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_DELRULE, h->family, 1993384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 1994384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_nlmsg_build_payload(nlh, r); 1995384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1996384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_print_debug(r, nlh); 1997384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1998384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 1999384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 2000384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_rule_del"); 2001384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2002384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 20033aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayusostatic struct nft_rule_list *nft_rule_list_create(struct nft_handle *h) 2004384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2005b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return nft_rule_list_get(h); 20063aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso} 20073aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 20083aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayusostatic void nft_rule_list_destroy(struct nft_rule_list *list) 20093aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso{ 20103aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_free(list); 20113aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso} 20123aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 20133aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayusostatic struct nft_rule * 20143aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayusonft_rule_find(struct nft_rule_list *list, const char *chain, const char *table, 20153aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct iptables_command_state *cs, int rulenum) 20163aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso{ 20173aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 20183aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list_iter *iter; 20193aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int rule_ctr = 0; 20203aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso bool found = false; 20213aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 2022384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 2023b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2024384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2025384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2026384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2027384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 2028384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 2029384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 2030384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 2031384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 2032077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka const struct nft_family_ops *ops = nft_family_ops_lookup( 2033077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY)); 2034384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct iptables_command_state this = {}; 2035384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2036384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 2037384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) { 2038384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different chain / table\n"); 2039384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2040384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2041384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2042384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (rulenum >= 0) { 2043384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete by rule number case */ 20444acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka if (rule_ctr != rulenum) 2045384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 20464acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka found = true; 20474acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka break; 2048384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2049384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete by matching rule case */ 2050384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("comparing with... "); 2051384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef DEBUG_DEL 20521ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso nft_rule_print_save(r, NFT_RULE_APPEND, 0); 2053384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 2054384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2055384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_to_iptables_command_state(r, &this); 2056384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2057077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka if (!ops->is_same(cs, &this)) 2058384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2059384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2060384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!find_matches(cs->matches, r)) { 2061384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("matches not found\n"); 2062384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2063384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2064384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2065384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!find_target(cs->target, r)) { 2066384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("target not found\n"); 2067384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2068384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2069384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2070384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!find_immediate(r, cs->jumpto)) { 2071384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("immediate not found\n"); 2072384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2073384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2074384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2075384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso found = true; 2076384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2077384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2078384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 20794acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka rule_ctr++; 2080384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2081384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2082384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2083384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_iter_destroy(iter); 2084384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 20853aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return found ? r : NULL; 2086384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2087384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2088384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_check(struct nft_handle *h, const char *chain, 2089384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, struct iptables_command_state *e, 2090384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool verbose) 2091384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 20923aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 20933aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret; 20943aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 2095384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_check; 2096384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 20973aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 2098b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 20993aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 21003aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21013aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso ret = nft_rule_find(list, chain, table, e, -1) ? 1 : 0; 21023aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (ret == 0) 21033aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 21043aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21053aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 21063aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21073aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 2108384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete(struct nft_handle *h, const char *chain, 21113aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso const char *table, struct iptables_command_state *cs, 2112384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool verbose) 2113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 21143aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 21153aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 21163aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 21173aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 2118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete; 2119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 21203aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 2121b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 21223aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 21233aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21243aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso r = nft_rule_find(list, chain, table, cs, -1); 21253aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 21263aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso ret = 1; 21273aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21289e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso if (h->commit) { 21299e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS, 21309e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso NFT_RULE_F_COMMIT); 21319e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 21323aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso DEBUGP("deleting rule\n"); 21333aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso __nft_rule_del(h, r); 21343aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 21353aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 21363aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21373aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 21383aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21393aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 2140384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2141384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete_num(struct nft_handle *h, const char *chain, 21433aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso const char *table, int rulenum, bool verbose) 2144384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 21453aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 21463aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 21473aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 21483aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 2149384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete_num; 2150384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 21513aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 2152b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 21533aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 21543aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21553aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso r = nft_rule_find(list, chain, table, NULL, rulenum); 21563aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 21573aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso ret = 1; 21583aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21599e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso if (h->commit) { 21609e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS, 21619e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso NFT_RULE_F_COMMIT); 21629e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 21633aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso DEBUGP("deleting rule by number %d\n", rulenum); 21643aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso __nft_rule_del(h, r); 21653aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 21663aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 21673aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21683aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 21693aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21703aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 2171384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2172384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2173384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_replace(struct nft_handle *h, const char *chain, 2174384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, struct iptables_command_state *cs, 2175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, bool verbose) 2176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 21773aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 21783aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 21793aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 2180384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2181384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_replace; 2182384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 21833aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 2184b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 21853aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 21863aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 21873aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso r = nft_rule_find(list, chain, table, cs, rulenum); 21883aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 21891298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso DEBUGP("replacing rule with handle=%llu\n", 21901298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso (unsigned long long) 21911298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE)); 2192384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 21939e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso if (h->commit) { 21949e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS, 21959e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso NFT_RULE_F_COMMIT); 21969e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 21973aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso ret = nft_rule_add(h, chain, table, cs, true, 21981298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE), 21993aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso verbose); 22003aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 22013aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 22023aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 22033aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 22043aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 22053aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 2206384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2207384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2208384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2209384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_header(unsigned int format, const char *chain, const char *pol, 2210384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters, bool basechain, uint32_t refs) 2211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("Chain %s", chain); 2213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (basechain) { 2214384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" (policy %s", pol); 2215384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOCOUNTS)) { 2216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(' ', stdout); 2217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_num(counters->pcnt, (format|FMT_NOTABLE)); 2218384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("packets, ", stdout); 2219384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_num(counters->bcnt, (format|FMT_NOTABLE)); 2220384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("bytes", stdout); 2221384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2222384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(")\n"); 2223384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2224384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" (%u references)\n", refs); 2225384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2226384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2227384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_LINENUMBERS) 2228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-4s ", "%s "), "num"); 2229384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOCOUNTS)) { 2230384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_KILOMEGAGIGA) { 2231384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%5s ","%s "), "pkts"); 2232384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%5s ","%s "), "bytes"); 2233384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2234384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%8s ","%s "), "pkts"); 2235384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%10s ","%s "), "bytes"); 2236384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2237384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2238384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOTARGET)) 2239384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-9s ","%s "), "target"); 2240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs(" prot ", stdout); 2241384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_OPTIONS) 2242384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("opt", stdout); 2243384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_VIA) { 2244384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-6s ","%s "), "in"); 2245384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-6s ","%s "), "out"); 2246384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2247384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-19s ","%s "), "source"); 2248384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-19s "," %s "), "destination"); 2249384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 2250384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2251384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2252384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2253384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_match(struct nft_rule_expr *expr, int numeric) 2254384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2255384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t len; 2256384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *match_name = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME); 2257384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *match_info = nft_rule_expr_get(expr, NFT_EXPR_MT_INFO, &len); 2258384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_match *match = 2259384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso xtables_find_match(match_name, XTF_TRY_LOAD, NULL); 2260384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_match *m = 2261384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso calloc(1, sizeof(struct xt_entry_match) + len); 2262384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2263384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* emulate struct xt_entry_match since ->print needs it */ 2264384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy((void *)&m->data, match_info, len); 2265384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2266384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match) { 2267384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match->print) 2268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing first parameter */ 2269384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso match->print(NULL, m, numeric); 2270384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2271384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("%s ", match_name); 2272384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (match_name[0]) 2274384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("UNKNOWN match `%s' ", match_name); 2275384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2276384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2277384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(m); 2278384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2279384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2280384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2281384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_firewall(const struct iptables_command_state *cs, struct nft_rule *r, 2282384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int num, unsigned int format) 2283384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2284384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xtables_target *target = NULL; 2285384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *targname = NULL; 2286384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const void *targinfo = NULL; 22870391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka int family; 2288077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka struct nft_family_ops *ops; 22890391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka uint8_t flags = 0; 2290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr_iter *iter; 2291384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 2292384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_entry_target *t; 2293384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso size_t target_len = 0; 2294384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2295384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 2296b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2297384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 2298384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2299384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 2301384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 2302384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 2303384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2304384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "target") == 0) { 23050391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka targname = nft_rule_expr_get_str(expr, 23060391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka NFT_EXPR_TG_NAME); 23070391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka targinfo = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, 23080391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka &target_len); 2309384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2310384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else if (strcmp(name, "immediate") == 0) { 2311384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t verdict = 2312384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT); 2313384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2314384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso switch(verdict) { 2315384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_ACCEPT: 2316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = "ACCEPT"; 2317384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2318384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NF_DROP: 2319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = "DROP"; 2320384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2321384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_RETURN: 2322384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso targname = "RETURN"; 2323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_GOTO: 23250391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka targname = nft_rule_expr_get_str(expr, 23260391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka NFT_EXPR_IMM_CHAIN); 2327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2328384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso case NFT_JUMP: 23290391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka targname = nft_rule_expr_get_str(expr, 23300391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka NFT_EXPR_IMM_CHAIN); 2331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 2332384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2333384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2335384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2336384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 2337384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 23380391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY); 2339077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka ops = nft_family_ops_lookup(family); 23400391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka 2341077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka flags = ops->print_firewall(cs, targname, num, format); 2342384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2343384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_NOTABLE) 2344384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs(" ", stdout); 2345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef IPT_F_GOTO 23470391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka if(flags & IPT_F_GOTO) 2348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("[goto] "); 2349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 2350384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_expr_iter_create(r); 2352b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 2354384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (expr != NULL) { 2357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *name = 2358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME); 2359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(name, "match") == 0) 2361384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso print_match(expr, format & FMT_NUMERIC); 2362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_iter_next(iter); 2364384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2365384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_iter_destroy(iter); 2366384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = calloc(1, sizeof(struct xt_entry_target) + target_len); 2368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (t == NULL) 2369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 2370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* emulate struct xt_entry_match since ->print needs it */ 2372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso memcpy((void *)&t->data, targinfo, target_len); 2373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (targname) { 2375384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target = xtables_find_target(targname, XTF_TRY_LOAD); 2376384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target) { 2377384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (target->print) 2378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* FIXME missing first parameter */ 2379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target->print(NULL, t, format & FMT_NUMERIC); 2380384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2381384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("[%ld bytes of unknown target data] ", 2382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso target_len); 2383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2384384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso free(t); 2385384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NONEWLINE)) 2387384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc('\n', stdout); 2388384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2389384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2390384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 2391384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_list(struct nft_handle *h, struct nft_chain *c, const char *table, 2392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format, 2393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void (*cb)(const struct iptables_command_state *cs, 2394384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r, unsigned int num, 2395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int format)) 2396384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 2398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list_iter *iter; 2399384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 2400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rule_ctr = 0, ret = 0; 2401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain = nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2402384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2403384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 2404b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 2405384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2406384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2407384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 2408b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2409b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2410384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2411384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2412384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 2413384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 2414384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 2415384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 2416384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 2417384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso rule_ctr++; 2419384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 2421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) 2422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 24240b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo if (rulenum > 0 && rule_ctr != rulenum) { 2425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* List by rule number case */ 24260b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo goto next; 24270b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo } 2428384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 24290b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo struct iptables_command_state cs = {}; 24300b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo /* Show all rules case */ 24310b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo nft_rule_to_iptables_command_state(r, &cs); 24320b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo 24330b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo cb(&cs, r, rule_ctr, format); 24340b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo if (rulenum > 0 && rule_ctr == rulenum) { 24350b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo ret = 1; 24360b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo break; 2437384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 24380b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo 2439384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2440384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 2441384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2442384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2443384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_iter_destroy(iter); 2444b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2445384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 2446384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2447384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == 0) 2448384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 2449384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2450384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 2451384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2452384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2453384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list(struct nft_handle *h, const char *chain, const char *table, 2454384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format) 2455384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2456384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 2457384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2458384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 24590a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo bool found = false; 2460384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2461aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka /* If built-in chains don't exist for this table, create them */ 2462aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 2463aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); 2464aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka 2465384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2466384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2467384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2468b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2469b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2470384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2471384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2472384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2473384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2474384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2475384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2476384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2477384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2478384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 2479384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t refs = 2480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_USE); 2481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_counters ctrs = { 2482384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .pcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS), 2483384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .bcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES), 2484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2485384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 2486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM)) 2488384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso basechain = true; 2489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2490384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2492384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2494384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 24950a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo if (found) 24960a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf("\n"); 24970a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 24980b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo if (!rulenum) { 24990b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo print_header(format, chain_name, policy_name[policy], 25000b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo &ctrs, basechain, refs); 25010b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo } 250206fc595fa99ab0036d87b259b0d20e4916522969Pablo Neira Ayuso __nft_rule_list(h, c, table, rulenum, format, print_firewall); 25030a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 25040a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo found = true; 25050a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 2506384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2507384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2508384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2509384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 251034c59adfae98515468ec50c644c30115fee0b97eGiuseppe Longo nft_chain_list_iter_destroy(iter); 2511b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2512384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 2513384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2515384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2518384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusolist_save(const struct iptables_command_state *cs, struct nft_rule *r, 2519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int num, unsigned int format) 2520384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 25211ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso nft_rule_print_save(r, NFT_RULE_APPEND, !(format & FMT_NOCOUNTS)); 2522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2524384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 2525384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonft_rule_list_chain_save(struct nft_handle *h, const char *table, 2526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list, int counters) 2527384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 2530384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2532b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2533384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2534384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2535384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2536384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2537384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2539384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2540384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 2543384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2544384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2545384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2547384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* this is a base chain */ 25487244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka if (nft_chain_builtin(c)) { 2549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-P %s %s", chain_name, policy_name[policy]); 2550384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2551384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 25520a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(" -c %"PRIu64" %"PRIu64"\n", 2553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS), 2554384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES)); 2555384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2556384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 2557384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2558384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-N %s\n", chain_name); 2559384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2560384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2561384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2562384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2563384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2564384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2565384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2566384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2567384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list_save(struct nft_handle *h, const char *chain, 2568384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, int rulenum, int counters) 2569384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2570384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 2571384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2572384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 257310f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso int ret = 1; 2574384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2575384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2576384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Dump policies and custom chains first */ 257810f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso if (!rulenum) 257910f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso nft_rule_list_chain_save(h, table, list, counters); 2580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Now dump out rules in this table */ 2582384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2583b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2584b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2585384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2586384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2587384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2588384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2589384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2591384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2592384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2593384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2594384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2595384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2596384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2597384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 259810f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso ret = __nft_rule_list(h, c, table, rulenum, 259910f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso counters ? 0 : FMT_NOCOUNTS, list_save); 2600384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2602384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2603b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2604384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 2605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 260610f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso return ret; 2607384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2608384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 26099e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayusostatic int nft_action(struct nft_handle *h, int type) 26109e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 26119e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 26129e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso struct nlmsghdr *nlh; 26139e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso uint32_t seq; 26149e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso int ret; 26159e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 26169e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nlh = mnl_nlmsg_put_header(buf); 26179e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nlh->nlmsg_type = (NFNL_SUBSYS_NFTABLES<< 8) | type; 26189e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 26199e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nlh->nlmsg_seq = seq = time(NULL); 26209e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 26219e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); 26223f7877e6be987bb94897c03a45945725389a6f5cPablo Neira Ayuso nfg->nfgen_family = h->family; 26239e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nfg->version = NFNETLINK_V0; 26249e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso nfg->res_id = 0; 26259e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 26269e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 26279e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso if (ret < 0) { 26289e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso if (errno != EEXIST) 26299e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso perror("mnl-talk:nft_commit"); 26309e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 2631f041efe3c26e3059df1ac8f1775f77423d4be5f6Pablo Neira Ayuso return ret == 0 ? 1 : 0; 26329e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 26339e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 26349e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayusoint nft_commit(struct nft_handle *h) 26359e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 26369e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso return nft_action(h, NFT_MSG_COMMIT); 26379e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 26389e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 26399e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayusoint nft_abort(struct nft_handle *h) 26409e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 26419e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso return nft_action(h, NFT_MSG_ABORT); 26429e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 26439e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2644384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_compatible_revision(const char *name, uint8_t rev, int opt) 2645384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2646384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct mnl_socket *nl; 2647384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 2648384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 2649384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t portid, seq, type; 2650384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 2651384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (opt == IPT_SO_GET_REVISION_MATCH) 2653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 0; 2654384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2655384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 1; 2656384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2657384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = mnl_nlmsg_put_header(buf); 2658384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET; 2659384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 2660384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_seq = seq = time(NULL); 2661384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2662384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); 2663384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->nfgen_family = AF_INET; 2664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->version = NFNETLINK_V0; 2665384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->res_id = 0; 2666384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2667384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_strz(nlh, NFTA_COMPAT_NAME, name); 2668384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_REV, htonl(rev)); 2669384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_TYPE, htonl(type)); 2670384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2671384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("requesting `%s' rev=%d type=%d via nft_compat\n", 2672384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name, rev, type); 2673384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nl = mnl_socket_open(NETLINK_NETFILTER); 2675384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nl == NULL) { 2676384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_open"); 2677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2678384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2679384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2680384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { 2681384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_bind"); 2682384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2683384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2684384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso portid = mnl_socket_get_portid(nl); 2685384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2686384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { 2687384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_send"); 2688384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2689384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2690384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2691384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); 2692384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 2693384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_recvfrom"); 2694384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2695384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2696384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); 2698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 2699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_cb_run"); 2700384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2703384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 2704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(nl); 2705384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2706384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret < 0 ? 0 : 1; 2707384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* Translates errno numbers into more human-readable form than strerror. */ 2710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoconst char *nft_strerror(int err) 2711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int i; 2713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso static struct table_struct { 2714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *fn; 2715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int err; 2716384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *message; 2717384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } table[] = 2718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { 2719384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, ENOTEMPTY, "Chain is not empty" }, 2720384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EINVAL, "Can't delete built-in chain" }, 2721384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EMLINK, 2722384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Can't delete chain with references left" }, 2723384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_add, EEXIST, "Chain already exists" }, 2724384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, E2BIG, "Index of insertion too big" }, 2725384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_replace, E2BIG, "Index of replacement too big" }, 2726384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete_num, E2BIG, "Index of deletion too big" }, 2727384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* { TC_READ_COUNTER, E2BIG, "Index of counter too big" }, 2728384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */ 2729384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, ELOOP, "Loop found in table" }, 2730384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, EINVAL, "Target problem" }, 2731384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* ENOENT for DELETE probably means no matching rule */ 2732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete, ENOENT, 2733384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Bad rule (does a matching rule exist in that chain?)" }, 2734384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, ENOENT, "Bad built-in chain name" }, 2735384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, EINVAL, "Bad policy name" }, 2736384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, EPERM, "Permission denied (you must be root)" }, 2737384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, 0, "Incompatible with this kernel" }, 2738384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" }, 2739384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOSYS, "Will be implemented real soon. I promise ;)" }, 2740384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOMEM, "Memory allocation problem" }, 2741384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOENT, "No chain/target/match by that name" }, 2742384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2743384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2744384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) { 2745384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if ((!table[i].fn || table[i].fn == nft_fn) 2746384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso && table[i].err == err) 2747384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return table[i].message; 2748384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2749384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2750384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return strerror(err); 2751384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 27528b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 27538b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayusostatic void xtables_config_perror(uint32_t flags, const char *fmt, ...) 27548b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso{ 27558b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_list args; 27568b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 27578b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_start(args, fmt); 27588b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 27598b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (flags & NFT_LOAD_VERBOSE) 27608b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso vfprintf(stderr, fmt, args); 27618b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 27628b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_end(args); 27638b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso} 27648b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 27658b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayusoint nft_xtables_config_load(struct nft_handle *h, const char *filename, 27668b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso uint32_t flags) 27678b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso{ 27688b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_table_list *table_list = nft_table_list_alloc(); 27698b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_chain_list *chain_list = nft_chain_list_alloc(); 27708b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_table_list_iter *titer; 27718b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_chain_list_iter *citer; 27728b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_table *table; 27738b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_chain *chain; 27748b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 27758b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (xtables_config_parse(filename, table_list, chain_list) < 0) { 27768b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == ENOENT) { 27778b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 27788b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "configuration file `%s' does not exists\n", 27798b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso filename); 27808b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 27818b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 27828b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "Fatal error parsing config file: %s\n", 27838b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 27848b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 27858b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso return -1; 27868b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 27878b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 27888b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso /* Stage 1) create tables */ 27898b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso titer = nft_table_list_iter_create(table_list); 27908b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso while ((table = nft_table_list_iter_next(titer)) != NULL) { 27918b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_table_add(h, table) < 0) { 27928b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == EEXIST) { 27938b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 27948b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "table `%s' already exists, skipping\n", 27958b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME)); 27968b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 27978b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 27988b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "table `%s' cannot be create, reason `%s'. Exitting\n", 27998b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME), 28008b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 28012c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_table_list_iter_destroy(titer); 28022c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_table_list_free(table_list); 28038b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso return -1; 28048b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 28058b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso continue; 28068b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 28078b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, "table `%s' has been created\n", 28088b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME)); 28098b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 28102c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_table_list_iter_destroy(titer); 28112c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_table_list_free(table_list); 28128b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 28138b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso /* Stage 2) create chains */ 28148b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso citer = nft_chain_list_iter_create(chain_list); 28158b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso while ((chain = nft_chain_list_iter_next(citer)) != NULL) { 28168b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_chain_add(h, chain) < 0) { 28178b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == EEXIST) { 28188b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 28198b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' already exists in table `%s', skipping\n", 28208b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME), 28218b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE)); 28228b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 28238b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 28248b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' cannot be create, reason `%s'. Exitting\n", 28258b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME), 28268b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 28272c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_chain_list_iter_destroy(citer); 28282c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_chain_list_free(chain_list); 28298b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso return -1; 28308b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 28318b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso continue; 28328b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 28338b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 28348b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 28358b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' in table `%s' has been created\n", 28368b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME), 28378b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE)); 28388b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 28392c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_chain_list_iter_destroy(citer); 28402c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_chain_list_free(chain_list); 28412c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso 28428b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso return 0; 28438b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso} 2844b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2845b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longoint nft_chain_zero_counters(struct nft_handle *h, const char *chain, 2846b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *table) 2847b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo{ 2848b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nft_chain_list *list; 2849b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nft_chain_list_iter *iter; 2850b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nft_chain *c; 2851b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nlmsghdr *nlh; 2852b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo char buf[MNL_SOCKET_BUFFER_SIZE]; 2853b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo int ret = 0; 2854b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2855b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo list = nft_chain_list_get(h); 2856b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (list == NULL) 2857b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto err; 2858b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2859b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo iter = nft_chain_list_iter_create(list); 2860b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2861b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2862b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2863b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo c = nft_chain_list_iter_next(iter); 2864b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo while (c != NULL) { 2865b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *chain_name = 2866b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_get(c, NFT_CHAIN_ATTR_NAME); 2867b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *chain_table = 2868b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_get(c, NFT_CHAIN_ATTR_TABLE); 2869b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2870b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (strcmp(table, chain_table) != 0) 2871b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto next; 2872b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2873b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (chain != NULL && strcmp(chain, chain_name) != 0) 2874b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto next; 2875b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2876b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, 0); 2877b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, 0); 2878b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2879b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_unset(c, NFT_CHAIN_ATTR_HANDLE); 2880b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2881b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, 2882b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo h->family, NLM_F_ACK, h->seq); 2883b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2884b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_nlmsg_build_payload(nlh, c); 2885b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2886b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo ret = mnl_talk(h, nlh, NULL, NULL); 2887b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (ret < 0) 2888b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo perror("mnl_talk:nft_chain_zero_counters"); 2889b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 289036ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 289136ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 2892b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longonext: 2893b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo c = nft_chain_list_iter_next(iter); 2894b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo } 2895b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2896b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_list_iter_destroy(iter); 2897b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2898b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longoerr: 2899b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_list_free(list); 2900b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2901b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo /* the core expects 1 for success and 0 for error */ 2902b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo return ret == 0 ? 1 : 0; 2903b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo} 2904b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2905