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> 41a4e1098169a67716a81316c36ce22ddcb33df1c0Tomasz Bursztyka#include <libnftnl/table.h> 42a4e1098169a67716a81316c36ce22ddcb33df1c0Tomasz Bursztyka#include <libnftnl/chain.h> 43a4e1098169a67716a81316c36ce22ddcb33df1c0Tomasz Bursztyka#include <libnftnl/rule.h> 44a4e1098169a67716a81316c36ce22ddcb33df1c0Tomasz Bursztyka#include <libnftnl/expr.h> 45f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso#include <libnftnl/set.h> 46d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay#include <libnftnl/udata.h> 47384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 48384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <netinet/in.h> /* inet_ntoa */ 49384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <arpa/inet.h> 50384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 51384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "nft.h" 52384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "xshared.h" /* proto_to_name */ 53077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include "nft-shared.h" 548b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso#include "xtables-config-parser.h" 55384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 56384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void *nft_fn; 57384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 5884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh, 5984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo int (*cb)(const struct nlmsghdr *nlh, void *data), 6084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo void *data) 61384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 62384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 63384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 64384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 65cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (mnl_socket_sendto(h->nl, nlh, nlh->nlmsg_len) < 0) 66384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 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 83d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic LIST_HEAD(batch_page_list); 84d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int batch_num_pages; 85d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 86d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostruct batch_page { 87d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct list_head head; 88d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct mnl_nlmsg_batch *batch; 89d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso}; 90d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 91d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso/* selected batch page is 256 Kbytes long to load ruleset of 92d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso * half a million rules without hitting -EMSGSIZE due to large 93d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso * iovec. 94d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso */ 95d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso#define BATCH_PAGE_SIZE getpagesize() * 32 96d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 97742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct mnl_nlmsg_batch *mnl_nftnl_batch_alloc(void) 98d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 99d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso static char *buf; 100d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 101d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso /* libmnl needs higher buffer to handle batch overflows */ 102d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso buf = malloc(BATCH_PAGE_SIZE + getpagesize()); 103d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (buf == NULL) 104d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return NULL; 105d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 106d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return mnl_nlmsg_batch_start(buf, BATCH_PAGE_SIZE); 107d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 108d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 109d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic struct mnl_nlmsg_batch * 110742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusomnl_nftnl_batch_page_add(struct mnl_nlmsg_batch *batch) 111d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 112d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct batch_page *batch_page; 113d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 114d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso batch_page = malloc(sizeof(struct batch_page)); 115d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (batch_page == NULL) 116d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return NULL; 117d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 118d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso batch_page->batch = batch; 119d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso list_add_tail(&batch_page->head, &batch_page_list); 120d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso batch_num_pages++; 121d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 122742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso return mnl_nftnl_batch_alloc(); 123d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 124d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 125d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int nlbuffsiz; 126d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 127d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic void mnl_nft_set_sndbuffer(const struct mnl_socket *nl) 128d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 129d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso int newbuffsiz; 130d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 131d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (batch_num_pages * BATCH_PAGE_SIZE <= nlbuffsiz) 132d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return; 133d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 134d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso newbuffsiz = batch_num_pages * BATCH_PAGE_SIZE; 135d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 136d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso /* Rise sender buffer length to avoid hitting -EMSGSIZE */ 137d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (setsockopt(mnl_socket_get_fd(nl), SOL_SOCKET, SO_SNDBUFFORCE, 138d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso &newbuffsiz, sizeof(socklen_t)) < 0) 139d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return; 140d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 141d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nlbuffsiz = newbuffsiz; 142d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 143d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 144742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic void mnl_nftnl_batch_reset(void) 1459470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso{ 1469470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso struct batch_page *batch_page, *next; 1479470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso 1489470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso list_for_each_entry_safe(batch_page, next, &batch_page_list, head) { 1499470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso list_del(&batch_page->head); 1509470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso free(batch_page->batch); 1519470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso free(batch_page); 1529470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso batch_num_pages--; 1539470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso } 1549470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso} 1559470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso 156d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic ssize_t mnl_nft_socket_sendmsg(const struct mnl_socket *nl) 157d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 158d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso static const struct sockaddr_nl snl = { 159d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .nl_family = AF_NETLINK 160d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso }; 161d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct iovec iov[batch_num_pages]; 162d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct msghdr msg = { 163d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_name = (struct sockaddr *) &snl, 164d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_namelen = sizeof(snl), 165d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_iov = iov, 166d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_iovlen = batch_num_pages, 167d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso }; 1689470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso struct batch_page *batch_page; 1699470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso int i = 0, ret; 170d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 171d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nft_set_sndbuffer(nl); 172d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 1739470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso list_for_each_entry(batch_page, &batch_page_list, head) { 174d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso iov[i].iov_base = mnl_nlmsg_batch_head(batch_page->batch); 175d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso iov[i].iov_len = mnl_nlmsg_batch_size(batch_page->batch); 176d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso i++; 177d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso#ifdef NL_DEBUG 178d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, 179d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_batch_head(batch_page->batch), 180d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_batch_size(batch_page->batch), 181d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso sizeof(struct nfgenmsg)); 182d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso#endif 183d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 184d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 1859470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso ret = sendmsg(mnl_socket_get_fd(nl), &msg, 0); 186742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_nftnl_batch_reset(); 1879470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso 1889470040d53ca7136b54f32507fe3d31d12736d22Pablo Neira Ayuso return ret; 189d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 190d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 191742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int mnl_nftnl_batch_talk(struct nft_handle *h) 192d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 193d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso int ret, fd = mnl_socket_get_fd(h->nl); 194d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso char rcv_buf[MNL_SOCKET_BUFFER_SIZE]; 195d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso fd_set readfds; 196d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct timeval tv = { 197d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .tv_sec = 0, 198d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .tv_usec = 0 199d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso }; 200d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso int err = 0; 201d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 202d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = mnl_nft_socket_sendmsg(h->nl); 203cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (ret == -1) 204d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 205d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 206d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_ZERO(&readfds); 207d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_SET(fd, &readfds); 208d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 209d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso /* receive and digest all the acknowledgments from the kernel. */ 210d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = select(fd+1, &readfds, NULL, NULL, &tv); 211cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (ret == -1) 212d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 213cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso 214d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso while (ret > 0 && FD_ISSET(fd, &readfds)) { 215d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, rcv_buf, sizeof(rcv_buf)); 216cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (ret == -1) 217d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 218d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2193f37696b7ce5bea29e742f7d8efc33dd82fb878cPablo Neira Ayuso ret = mnl_cb_run(rcv_buf, ret, 0, h->portid, NULL, NULL); 2203f37696b7ce5bea29e742f7d8efc33dd82fb878cPablo Neira Ayuso /* Annotate first error and continue, make sure we get all 2213f37696b7ce5bea29e742f7d8efc33dd82fb878cPablo Neira Ayuso * acknoledgments. 2223f37696b7ce5bea29e742f7d8efc33dd82fb878cPablo Neira Ayuso */ 2233f37696b7ce5bea29e742f7d8efc33dd82fb878cPablo Neira Ayuso if (!err && ret == -1) 224d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso err = errno; 225d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 226d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = select(fd+1, &readfds, NULL, NULL, &tv); 227cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (ret == -1) 228d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 229cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso 230d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_ZERO(&readfds); 231d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_SET(fd, &readfds); 232d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 2333f37696b7ce5bea29e742f7d8efc33dd82fb878cPablo Neira Ayuso errno = err; 234d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return err ? -1 : 0; 235d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 236d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 237742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic void mnl_nftnl_batch_begin(struct mnl_nlmsg_batch *batch, uint32_t seq) 238d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 239742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_batch_begin(mnl_nlmsg_batch_current(batch), seq); 240d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (!mnl_nlmsg_batch_next(batch)) 241742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_nftnl_batch_page_add(batch); 242d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 243d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 244742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic void mnl_nftnl_batch_end(struct mnl_nlmsg_batch *batch, uint32_t seq) 245d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 246742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_batch_end(mnl_nlmsg_batch_current(batch), seq); 2471f932f08a17c55f1689a432433f9f2a0cf6f014fPablo Neira Ayuso if (!mnl_nlmsg_batch_next(batch)) 248742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_nftnl_batch_page_add(batch); 249d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 250d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 251f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusoenum obj_update_type { 252f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_TABLE_ADD, 253f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_CHAIN_ADD, 2541d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso NFT_COMPAT_CHAIN_USER_ADD, 2551d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso NFT_COMPAT_CHAIN_USER_DEL, 256f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_CHAIN_UPDATE, 257d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero NFT_COMPAT_CHAIN_RENAME, 258f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_RULE_APPEND, 259f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_RULE_INSERT, 260f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_RULE_REPLACE, 261f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_RULE_DELETE, 262f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_RULE_FLUSH, 263f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso}; 264f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 265f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusoenum obj_action { 266f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_COMMIT, 267f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_COMPAT_ABORT, 268f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso}; 269f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 270f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostruct obj_update { 271f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso struct list_head head; 272f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso enum obj_update_type type; 273f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso union { 274742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *table; 275742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *chain; 276742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *rule; 277f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso void *ptr; 278f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso }; 279f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso}; 280f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 281f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic int batch_add(struct nft_handle *h, enum obj_update_type type, void *ptr) 282f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 283f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso struct obj_update *obj; 284f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 285f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso obj = calloc(1, sizeof(struct obj_update)); 286f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (obj == NULL) 287f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return -1; 288f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 289f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso obj->ptr = ptr; 290f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso obj->type = type; 291f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso list_add_tail(&obj->head, &h->obj_list); 292f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso h->obj_list_num++; 293f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 294f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return 0; 295f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 296f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 297f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic int batch_table_add(struct nft_handle *h, enum obj_update_type type, 298742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *t) 299f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 300f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return batch_add(h, type, t); 301f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 302f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 303f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic int batch_chain_add(struct nft_handle *h, enum obj_update_type type, 304742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c) 305f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 306f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return batch_add(h, type, c); 307f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 308f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 309f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic int batch_rule_add(struct nft_handle *h, enum obj_update_type type, 310742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r) 311f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 312f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return batch_add(h, type, r); 313f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 314f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 315afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longostruct builtin_table xtables_ipv4[TABLES_MAX] = { 316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [RAW] = { 317384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "raw", 318e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 319e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 320e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 321890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3225b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -300, /* NF_IP_PRI_RAW */ 323e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 324e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 325e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 326e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 327890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3285b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -300, /* NF_IP_PRI_RAW */ 329e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 330e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 331e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 332384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 333384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [MANGLE] = { 334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "mangle", 335e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 336e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 337e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 338890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3395b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 340e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 341e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 342e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 343e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 344890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3455b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 346e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 347e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 348e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 349e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 350890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3515b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 352e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 353e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 354e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 355e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 356890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "route", 3575b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 358e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 359e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 360e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 361e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "POSTROUTING", 362890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3635b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 364e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_POST_ROUTING, 365e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 366e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [FILTER] = { 369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "filter", 370e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 371e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 372e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 373890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3745b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 375e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 376e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 377e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 378e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 379890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3805b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 381e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 382e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 383e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 384e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 385890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3865b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 387e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 388e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 389e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 390384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 391384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [SECURITY] = { 392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "security", 393e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 394e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 395e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 396890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3975b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 398e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 399e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 400e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 401e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 402890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 4035b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 404e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 405e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 406e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 407e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 408890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 4095b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 410e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 411e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 412384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 413384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 414890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso [NAT] = { 415890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "nat", 416890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .chains = { 417890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 41886eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .name = "PREROUTING", 419890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 420890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = -100, /* NF_IP_PRI_NAT_DST */ 42186eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 422890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 423890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 424890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "INPUT", 425890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 426890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = 100, /* NF_IP_PRI_NAT_SRC */ 427890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 428890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 429890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 430890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "POSTROUTING", 431890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 432890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = 100, /* NF_IP_PRI_NAT_SRC */ 433890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_POST_ROUTING, 434890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 43586eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso { 43686eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .name = "OUTPUT", 43786eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .type = "nat", 43886eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .prio = -100, /* NF_IP_PRI_NAT_DST */ 43986eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 44086eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso }, 441890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 442890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 443384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 444384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 44584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo#include <linux/netfilter_arp.h> 44684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo 44784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longostruct builtin_table xtables_arp[TABLES_MAX] = { 44884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo [FILTER] = { 44984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "filter", 45084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .chains = { 45184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo { 45284909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "INPUT", 45384909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .type = "filter", 45484909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .prio = NF_IP_PRI_FILTER, 45584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .hook = NF_ARP_IN, 45684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 45784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo { 45884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "FORWARD", 45984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .type = "filter", 46084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .prio = NF_IP_PRI_FILTER, 46184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .hook = NF_ARP_FORWARD, 46284909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 46384909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo { 46484909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "OUTPUT", 46584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .type = "filter", 46684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .prio = NF_IP_PRI_FILTER, 46784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .hook = NF_ARP_OUT, 46884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 46984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 47084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 47184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo}; 47284909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo 473da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso#include <linux/netfilter_bridge.h> 474da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso 475da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayusostruct builtin_table xtables_bridge[TABLES_MAX] = { 476da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso [FILTER] = { 477da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "filter", 478da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .chains = { 479da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso { 480da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "INPUT", 481da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .type = "filter", 482da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .prio = NF_BR_PRI_FILTER_BRIDGED, 483da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .hook = NF_BR_LOCAL_IN, 484da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 485da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso { 486da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "FORWARD", 487da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .type = "filter", 488da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .prio = NF_BR_PRI_FILTER_BRIDGED, 489da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .hook = NF_BR_FORWARD, 490da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 491da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso { 492da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "OUTPUT", 493da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .type = "filter", 494da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .prio = NF_BR_PRI_FILTER_BRIDGED, 495da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .hook = NF_BR_LOCAL_OUT, 496da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 497da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 498da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 499da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso [NAT] = { 500da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "nat", 501da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .chains = { 502da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso { 503da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "PREROUTING", 504da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .type = "filter", 505da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .prio = NF_BR_PRI_NAT_DST_BRIDGED, 506da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .hook = NF_BR_PRE_ROUTING, 507da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 508da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso { 509da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "OUTPUT", 510da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .type = "filter", 511da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .prio = NF_BR_PRI_NAT_DST_OTHER, 512da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .hook = NF_BR_LOCAL_OUT, 513da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 514da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso { 515da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .name = "POSTROUTING", 516da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .type = "filter", 517da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .prio = NF_BR_PRI_NAT_SRC, 518da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso .hook = NF_BR_POST_ROUTING, 519da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 520da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 521da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso }, 522da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso}; 523da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso 524742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint nft_table_add(struct nft_handle *h, struct nftnl_table *t, uint16_t flags) 5255b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso{ 5265b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 5275b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso struct nlmsghdr *nlh; 5285b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso int ret; 5295b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 530742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family, 531f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_ACK|flags, h->seq); 532742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_nlmsg_build_payload(nlh, t); 533742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_free(t); 5345b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 535837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka#ifdef NLDEBUG 536837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka char tmp[1024]; 537837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka 538837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka nft_table_snprintf(tmp, sizeof(tmp), t, 0, 0); 5391835790d7f7517f4c101e1c1f3df5519a6c228e7Tomasz Bursztyka printf("DEBUG: table: %s\n", tmp); 540837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 541837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka#endif 542837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka 5435b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 544f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 545f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return (ret == 0 || (ret == -1 && errno == EEXIST)) ? 0 : -1; 546f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 547f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 548f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic int nft_table_builtin_add(struct nft_handle *h, 549f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso struct builtin_table *_t) 550f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 551742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *t; 552f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso int ret; 553f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 554f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (_t->initialized) 555f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return 0; 556f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 557742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso t = nftnl_table_alloc(); 558f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (t == NULL) 559f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return -1; 560f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 561742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_set(t, NFTNL_TABLE_NAME, (char *)_t->name); 562f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 563f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (h->batch_support) 564f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = batch_table_add(h, NFT_COMPAT_TABLE_ADD, t); 565f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso else 566f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = nft_table_add(h, t, NLM_F_EXCL); 567f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 568f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (ret == 0) 569e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka _t->initialized = true; 570e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka 5715b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso return ret; 5725b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso} 5735b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 574742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_chain * 575c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_alloc(struct builtin_table *table, 576c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *chain, int policy) 577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 578742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 579384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 580742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_alloc(); 581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) 582c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return NULL; 583384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 584742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table->name); 585742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)chain->name); 586742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM, chain->hook); 587742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u32(c, NFTNL_CHAIN_PRIO, chain->prio); 588742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy); 589742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set(c, NFTNL_CHAIN_TYPE, (char *)chain->type); 590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 591c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return c; 592c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 593c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 594742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint nft_chain_add(struct nft_handle *h, struct nftnl_chain *c, uint16_t flags) 595c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 596c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 597c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct nlmsghdr *nlh; 598c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 599890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso /* NLM_F_CREATE requests module autoloading */ 600742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 601f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_ACK|flags|NLM_F_CREATE, 602890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso h->seq); 603742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_nlmsg_build_payload(nlh, c); 604742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_free(c); 605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 606f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso#ifdef NLDEBUG 607f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso char tmp[1024]; 608f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 609f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0); 610f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso printf("DEBUG: chain: %s\n", tmp); 611f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 612f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso#endif 613f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 614f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 615f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 616f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 61763f1391a5441bb092f7a1a4023e2f158ee9231a2Pablo Neira Ayusostatic void nft_chain_builtin_add(struct nft_handle *h, 61863f1391a5441bb092f7a1a4023e2f158ee9231a2Pablo Neira Ayuso struct builtin_table *table, 6193599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso struct builtin_chain *chain) 620f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 621742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 622f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 6233599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso c = nft_chain_builtin_alloc(table, chain, NF_ACCEPT); 624f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (c == NULL) 625f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return; 626f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 627f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (h->batch_support) 628f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c); 629f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso else 630f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_chain_add(h, c, NLM_F_EXCL); 631c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 632c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 633c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in table already exists */ 63463f1391a5441bb092f7a1a4023e2f158ee9231a2Pablo Neira Ayusostatic struct builtin_table * 63584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longonft_table_builtin_find(struct nft_handle *h, const char *table) 636c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 637c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int i; 638c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 639c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 640c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso for (i=0; i<TABLES_MAX; i++) { 64167da6075a4e7ced0e8cc452d73ce8ab06cbf8cd9Tomasz Bursztyka if (h->tables[i].name == NULL) 642da871de2a6efb576b6378a66222c0871f4282e96Pablo Neira Ayuso continue; 64367da6075a4e7ced0e8cc452d73ce8ab06cbf8cd9Tomasz Bursztyka 644afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo if (strcmp(h->tables[i].name, table) != 0) 645c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso continue; 646c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 647c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso found = true; 648c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso break; 649384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 650c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 651afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo return found ? &h->tables[i] : NULL; 652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 654c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in chain already exists */ 65563f1391a5441bb092f7a1a4023e2f158ee9231a2Pablo Neira Ayusostatic struct builtin_chain * 656e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusonft_chain_builtin_find(struct builtin_table *t, const char *chain) 657384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 658e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int i; 659c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 660384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 661e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && t->chains[i].name != NULL; i++) { 662e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (strcmp(t->chains[i].name, chain) != 0) 663e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso continue; 664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 665e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso found = true; 666e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso break; 667e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso } 668e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso return found ? &t->chains[i] : NULL; 669e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso} 670e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 6713599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayusostatic void nft_chain_builtin_init(struct nft_handle *h, 6723599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso struct builtin_table *table) 673e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso{ 6743599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso int i; 675742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list = nft_chain_dump(h); 676742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 677e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 678b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso /* Initialize built-in chains if they don't exist yet */ 679e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && table->chains[i].name != NULL; i++) { 680b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso 681b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso c = nft_chain_list_find(list, table->name, 682b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso table->chains[i].name); 683b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso if (c != NULL) 684b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso continue; 685b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso 6863599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso nft_chain_builtin_add(h, table, &table->chains[i]); 687384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 688b06fcdb858deefe35baaaf2f2f912616fb38644bPablo Neira Ayuso 689742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(list); 690c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 691c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 6923599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayusostatic int nft_xt_builtin_init(struct nft_handle *h, const char *table) 693c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 694c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int ret = 0; 695c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *t; 696c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 697afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo t = nft_table_builtin_find(h, table); 698c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (t == NULL) { 699c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso ret = -1; 700c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso goto out; 701c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 702ee85b1bc1bb9f91daf2004823dfa204dbc52f52aPablo Neira Ayuso if (nft_table_builtin_add(h, t) < 0) { 703e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* Built-in table already initialized, skip. */ 704e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (errno == EEXIST) 705e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso goto out; 706c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 7073599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso nft_chain_builtin_init(h, t); 708c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusoout: 709c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return ret; 710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 712742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic bool nft_chain_builtin(struct nftnl_chain *c) 7137244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka{ 7147244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka /* Check if this chain has hook number, in that case is built-in. 7157244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka * Should we better export the flags to user-space via nf_tables? 7167244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka */ 717742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso return nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM) != NULL; 7187244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka} 7197244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka 720f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic bool mnl_batch_supported(struct nft_handle *h) 721f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 722f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 723f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso uint32_t seq = 1; 724f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso int ret; 725f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 726742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_nftnl_batch_begin(h->batch, seq++); 727f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 728742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch), 729f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NFT_MSG_NEWSET, AF_INET, 730f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_ACK, seq++); 731f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso mnl_nlmsg_batch_next(h->batch); 732f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 733742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_nftnl_batch_end(h->batch, seq++); 734f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 735f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = mnl_socket_sendto(h->nl, mnl_nlmsg_batch_head(h->batch), 736f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso mnl_nlmsg_batch_size(h->batch)); 737f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (ret < 0) 738f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso goto err; 739f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 740f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso mnl_nlmsg_batch_reset(h->batch); 741f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 742f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 743f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso while (ret > 0) { 744f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = mnl_cb_run(buf, ret, 0, mnl_socket_get_portid(h->nl), 745f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NULL, NULL); 746f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (ret <= 0) 747f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso break; 748f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 749f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 750f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso } 751f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 752f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso /* We're sending an incomplete message to see if the kernel supports 753f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso * set messages in batches. EINVAL means that we sent an incomplete 754f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso * message with missing attributes. The kernel just ignores messages 755f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso * that we cannot include in the batch. 756f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso */ 757f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return (ret == -1 && errno == EINVAL) ? true : false; 758f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusoerr: 759f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso mnl_nlmsg_batch_reset(h->batch); 760f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return ret; 761f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 762f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 763afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longoint nft_init(struct nft_handle *h, struct builtin_table *t) 764384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 765384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->nl = mnl_socket_open(NETLINK_NETFILTER); 766cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (h->nl == NULL) 767384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 768384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 769cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0) 770384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 771cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso 772384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->portid = mnl_socket_get_portid(h->nl); 773afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo h->tables = t; 774384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 775495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso INIT_LIST_HEAD(&h->obj_list); 776d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 777742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso h->batch = mnl_nftnl_batch_alloc(); 778f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso h->batch_support = mnl_batch_supported(h); 779d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 780384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 781384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 783ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garaystatic void flush_rule_cache(struct nft_handle *h) 784ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay{ 785ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay if (!h->rule_cache) 786ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay return; 787ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay 788ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay nftnl_rule_list_free(h->rule_cache); 789ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay h->rule_cache = NULL; 790ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay} 791ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay 792384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusovoid nft_fini(struct nft_handle *h) 793384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 794ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 795384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(h->nl); 796b0194cea194b510c675ca05415da15cff57afe47Ana Rey free(mnl_nlmsg_batch_head(h->batch)); 797b0194cea194b510c675ca05415da15cff57afe47Ana Rey mnl_nlmsg_batch_stop(h->batch); 798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 799384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 800742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic void nft_chain_print_debug(struct nftnl_chain *c, struct nlmsghdr *nlh) 801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 802384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 803384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0); 8061835790d7f7517f4c101e1c1f3df5519a6c228e7Tomasz Bursztyka printf("DEBUG: chain: %s\n", tmp); 807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 810384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 811742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_chain *nft_chain_new(struct nft_handle *h, 812f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso const char *table, const char *chain, 813f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso int policy, 814f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso const struct xt_counters *counters) 815384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 816742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 817c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *_t; 818c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *_c; 819c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 820afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo _t = nft_table_builtin_find(h, table); 821c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* if this built-in table does not exists, create it */ 822c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_t != NULL) 823ee85b1bc1bb9f91daf2004823dfa204dbc52f52aPablo Neira Ayuso nft_table_builtin_add(h, _t); 824c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 825e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso _c = nft_chain_builtin_find(_t, chain); 826c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_c != NULL) { 827c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* This is a built-in chain */ 828c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_builtin_alloc(_t, _c, policy); 829c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 830f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return NULL; 831c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } else { 83220c156f9f4c43857a622f015a3022517601c3600Tomasz Bursztyka errno = ENOENT; 833f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return NULL; 834c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 835384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 836384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 837742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->bcnt); 839742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->pcnt); 841384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 842384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 843f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return c; 844384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 845384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 846384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_set(struct nft_handle *h, const char *table, 847384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain, const char *policy, 848384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters) 849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 850742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c = NULL; 851f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso int ret; 852384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 853384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_chain_set; 854384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 855384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(policy, "DROP") == 0) 856f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso c = nft_chain_new(h, table, chain, NF_DROP, counters); 857384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(policy, "ACCEPT") == 0) 858f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso c = nft_chain_new(h, table, chain, NF_ACCEPT, counters); 859f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 860f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (c == NULL) 861f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso return 0; 862f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 863f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (h->batch_support) 864f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c); 865f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso else 866f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso ret = nft_chain_add(h, c, 0); 867384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 868384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 869384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 870384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 871384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 872742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int __add_match(struct nftnl_expr *e, struct xt_entry_match *m) 873384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *info; 875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 876742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set(e, NFTNL_EXPR_MT_NAME, m->u.user.name, strlen(m->u.user.name)); 877742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u32(e, NFTNL_EXPR_MT_REV, m->u.user.revision); 878384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 879384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso info = calloc(1, m->u.match_size); 880384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) 881f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 882384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 8835eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso memcpy(info, m->data, m->u.match_size - sizeof(*m)); 884742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set(e, NFTNL_EXPR_MT_INFO, info, m->u.match_size - sizeof(*m)); 885f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 886f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 887384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 888384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 889742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint add_match(struct nftnl_rule *r, struct xt_entry_match *m) 890384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 891742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_expr *expr; 892f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka int ret; 893384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 894742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso expr = nftnl_expr_alloc("match"); 895384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 896f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 897384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 898f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = __add_match(expr, m); 899742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_add_expr(r, expr); 900f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 901f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return ret; 902384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 903384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 904742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int __add_target(struct nftnl_expr *e, struct xt_entry_target *t) 905384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 9065eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso void *info; 907384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 908742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set(e, NFTNL_EXPR_TG_NAME, t->u.user.name, 909384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strlen(t->u.user.name)); 910742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u32(e, NFTNL_EXPR_TG_REV, t->u.user.revision); 911384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 9125eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso info = calloc(1, t->u.target_size); 9135eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso if (info == NULL) 9145eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso return -ENOMEM; 915384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 9165eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso memcpy(info, t->data, t->u.target_size - sizeof(*t)); 917742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set(e, NFTNL_EXPR_TG_INFO, info, t->u.target_size - sizeof(*t)); 918f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 919f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 920384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 921384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 922742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint add_target(struct nftnl_rule *r, struct xt_entry_target *t) 923384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 924742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_expr *expr; 925f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka int ret; 926384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 927742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso expr = nftnl_expr_alloc("target"); 928384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 929f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 930384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 931f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = __add_target(expr, t); 932742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_add_expr(r, expr); 933f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 934f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return ret; 935384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 936384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 937742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint add_jumpto(struct nftnl_rule *r, const char *name, int verdict) 938384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 939742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_expr *expr; 940384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 941742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso expr = nftnl_expr_alloc("immediate"); 942384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 943f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 944384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 945742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG_VERDICT); 946742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_VERDICT, verdict); 947742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_str(expr, NFTNL_EXPR_IMM_CHAIN, (char *)name); 948742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_add_expr(r, expr); 949f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 950f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 951384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 952384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 953742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint add_verdict(struct nftnl_rule *r, int verdict) 954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 955742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_expr *expr; 956384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 957742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso expr = nftnl_expr_alloc("immediate"); 958384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 959f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 960384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 961742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG_VERDICT); 962742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_VERDICT, verdict); 963742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_add_expr(r, expr); 964f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 965f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 966384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 967384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 968742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint add_action(struct nftnl_rule *r, struct iptables_command_state *cs, 969d007e1a59e4beaddab430992302d43b122ffc801Pablo Neira Ayuso bool goto_set) 970c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso{ 971c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso int ret = 0; 972c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso 973c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso /* If no target at all, add nothing (default to continue) */ 974c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso if (cs->target != NULL) { 975c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso /* Standard target? */ 976c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0) 977c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_verdict(r, NF_ACCEPT); 978c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0) 979c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_verdict(r, NF_DROP); 980c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0) 981c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_verdict(r, NFT_RETURN); 982c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else 983c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_target(r, cs->target->t); 984c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso } else if (strlen(cs->jumpto) > 0) { 985c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso /* Not standard, then it's a go / jump to chain */ 986d007e1a59e4beaddab430992302d43b122ffc801Pablo Neira Ayuso if (goto_set) 987c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_jumpto(r, cs->jumpto, NFT_GOTO); 988c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else 989c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_jumpto(r, cs->jumpto, NFT_JUMP); 990c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso } 991c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso return ret; 992c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso} 993c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso 994742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic void nft_rule_print_debug(struct nftnl_rule *r, struct nlmsghdr *nlh) 995384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 996384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 997384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 998384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 999384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0); 10001835790d7f7517f4c101e1c1f3df5519a6c228e7Tomasz Bursztyka printf("DEBUG: rule: %s\n", tmp); 1001384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 1002384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 1003384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1004384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1005742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint add_counters(struct nftnl_rule *r, uint64_t packets, uint64_t bytes) 1006384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1007742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_expr *expr; 1008384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1009742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso expr = nftnl_expr_alloc("counter"); 1010384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 1011f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 1012384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1013742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u64(expr, NFTNL_EXPR_CTR_PACKETS, packets); 1014742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_expr_set_u64(expr, NFTNL_EXPR_CTR_BYTES, bytes); 1015384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1016742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_add_expr(r, expr); 1017f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 1018f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 1019384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1020384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1021d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garayenum udata_type { 1022d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay UDATA_TYPE_COMMENT, 1023d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay __UDATA_TYPE_MAX, 1024d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay}; 1025d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay#define UDATA_TYPE_MAX (__UDATA_TYPE_MAX - 1) 1026d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay 1027d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garayint add_comment(struct nftnl_rule *r, const char *comment) 1028d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay{ 1029d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay struct nftnl_udata_buf *udata; 1030d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay 1031d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN); 1032d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay if (!udata) 1033d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay return -ENOMEM; 1034d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay 1035d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay if (!nftnl_udata_put_strz(udata, UDATA_TYPE_COMMENT, comment)) 1036d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay return -ENOMEM; 1037d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay nftnl_rule_set_data(r, NFTNL_RULE_USERDATA, 1038d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay nftnl_udata_buf_data(udata), 1039d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay nftnl_udata_buf_len(udata)); 1040d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay 1041d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay nftnl_udata_buf_free(udata); 1042d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay 1043d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay return 0; 1044d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay} 1045d64ef34a99610a6fb54d43660ac31555da858231Pablo M. Bermudo Garay 1046a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garaystatic int parse_udata_cb(const struct nftnl_udata *attr, void *data) 1047a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay{ 1048a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay unsigned char *value = nftnl_udata_get(attr); 1049a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay uint8_t type = nftnl_udata_type(attr); 1050a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay uint8_t len = nftnl_udata_len(attr); 1051a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay const struct nftnl_udata **tb = data; 1052a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay 1053a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay switch (type) { 1054a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay case UDATA_TYPE_COMMENT: 1055a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay if (value[len - 1] != '\0') 1056a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay return -1; 1057a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay break; 1058a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay default: 1059a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay return 0; 1060a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay } 1061a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay tb[type] = attr; 1062a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay return 0; 1063a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay} 1064a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay 1065a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garaychar *get_comment(const void *data, uint32_t data_len) 1066a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay{ 1067a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay const struct nftnl_udata *tb[UDATA_TYPE_MAX + 1] = {}; 1068a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay 1069a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay if (nftnl_udata_parse(data, data_len, parse_udata_cb, tb) < 0) 1070a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay return NULL; 1071a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay 1072a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay if (!tb[UDATA_TYPE_COMMENT]) 1073a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay return NULL; 1074a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay 1075a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay return nftnl_udata_get(tb[UDATA_TYPE_COMMENT]); 1076a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay} 1077a44bee8c3582cb72868a3b7f703494dd2b24bf7dPablo M. Bermudo Garay 1078742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusovoid add_compat(struct nftnl_rule *r, uint32_t proto, bool inv) 10792a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso{ 1080742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set_u32(r, NFTNL_RULE_COMPAT_PROTO, proto); 1081742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set_u32(r, NFTNL_RULE_COMPAT_FLAGS, 10822a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso inv ? NFT_RULE_COMPAT_F_INV : 0); 10832a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso} 10842a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso 1085742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_rule * 1086cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusonft_rule_new(struct nft_handle *h, const char *chain, const char *table, 1087c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso void *data) 1088384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1089742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1090384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1091742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_alloc(); 1092cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso if (r == NULL) 1093cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return NULL; 1094384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1095742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, h->family); 1096742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set(r, NFTNL_RULE_TABLE, (char *)table); 1097742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set(r, NFTNL_RULE_CHAIN, (char *)chain); 1098384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1099c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso if (h->ops->add(r, data) < 0) 1100cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso goto err; 1101cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1102cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return r; 1103cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoerr: 1104742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_free(r); 1105cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return NULL; 1106cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso} 1107cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1108cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoint 1109cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusonft_rule_append(struct nft_handle *h, const char *chain, const char *table, 1110b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso void *data, uint64_t handle, bool verbose) 1111cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso{ 1112742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1113d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso int type; 1114cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1115cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 1116cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 11173599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso nft_xt_builtin_init(h, table); 1118cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1119cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_fn = nft_rule_append; 1120cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1121b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_new(h, chain, table, data); 1122d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (r == NULL) 1123d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 1124384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11250a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka if (handle > 0) { 1126742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set(r, NFTNL_RULE_HANDLE, &handle); 1127495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso type = NFT_COMPAT_RULE_REPLACE; 1128cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso } else 1129495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso type = NFT_COMPAT_RULE_APPEND; 1130384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1131495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso if (batch_rule_add(h, type, r) < 0) 1132742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_free(r); 1133384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1134ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 1135d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 1; 1136384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1137384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11381ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayusovoid 11398877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longonft_rule_print_save(const void *data, 1140742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r, enum nft_rule_print type, 1141cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka unsigned int format) 1142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1143742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso const char *chain = nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); 1144742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY); 1145cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka struct nft_family_ops *ops; 1146384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11471aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo ops = nft_family_ops_lookup(family); 11481aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo 11491aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo if (!(format & FMT_NOCOUNTS) && ops->save_counters) 11501aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo ops->save_counters(data); 11511aefddd07ca8e51f0528366835cf466d57bd459fGiuseppe Longo 1152384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 11531ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso switch(type) { 11541ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso case NFT_RULE_APPEND: 11551ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso printf("-A %s ", chain); 11561ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso break; 11571ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso case NFT_RULE_DEL: 11581ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso printf("-D %s ", chain); 11591ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso break; 11601ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso } 1161384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11628877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo if (ops->save_firewall) 11638877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo ops->save_firewall(data, format); 1164cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 1165384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1166384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1167742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) 1168384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1169742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 1170742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list = data; 1171384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1172742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_alloc(); 1173cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (c == NULL) 1174384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1176742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso if (nftnl_chain_nlmsg_parse(nlh, c) < 0) 1177384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1178384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1179742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_add_tail(c, list); 1180384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1181384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1182384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1183742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_free(c); 1184384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1185384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1186384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1187384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1188742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h) 1189384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1190384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1191384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1192742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list; 1193384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1194742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_chain_list_alloc(); 1195384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1196b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso errno = ENOMEM; 1197b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return NULL; 1198384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1199384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1200742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, 1201384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1202384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1203742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_talk(h, nlh, nftnl_chain_list_cb, list); 1204384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1205384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1206384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1207384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1208742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostruct nftnl_chain_list *nft_chain_dump(struct nft_handle *h) 1209384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1210742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso return nftnl_chain_list_get(h); 1211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic const char *policy_name[NF_ACCEPT+1] = { 1214384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_DROP] = "DROP", 1215384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_ACCEPT] = "ACCEPT", 1216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 1217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1218742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic void nft_chain_print_save(struct nftnl_chain *c, bool basechain) 1219384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1220742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); 1221742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso uint64_t pkts = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS); 1222742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso uint64_t bytes = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES); 1223384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1224384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 1225384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (basechain) { 1226384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t pol = NF_ACCEPT; 1227384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* no default chain policy? don't crash, display accept */ 1229742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY)) 1230742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); 1231384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 12320a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(":%s %s [%"PRIu64":%"PRIu64"]\n", chain, policy_name[pol], 1233384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso pkts, bytes); 1234384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 12350a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(":%s - [%"PRIu64":%"PRIu64"]\n", chain, pkts, bytes); 1236384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1237384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1238742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusoint nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, 1239384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table) 1240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1241742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 1242742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 1243384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1244742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 1245b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1246384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1247384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1248742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 1249384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1250384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 1251742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); 1252384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 1253384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1254384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 1255384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1256384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 12577244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka basechain = nft_chain_builtin(c); 1258384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_print_save(c, basechain); 1259384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1260742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 1261384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1262384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1263742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 1264742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(list); 1265384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1266384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1267384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1269742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data) 1270384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1271742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1272742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list = data; 1273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1274742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_alloc(); 1275cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (r == NULL) 1276384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1277384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1278742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso if (nftnl_rule_nlmsg_parse(nlh, r) < 0) 1279384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1280384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1281742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_add_tail(r, list); 1282384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1283384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1284384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1285742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_free(r); 1286742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_free(list); 1287384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1288384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1289384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1291742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h) 1292384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1293384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1294384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1295742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 1296384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1297384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1298ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay if (h->rule_cache) 1299ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay return h->rule_cache; 1300ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay 1301742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_rule_list_alloc(); 1302b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1303384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1304384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1305742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family, 1306384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1307384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1308742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso ret = mnl_talk(h, nlh, nftnl_rule_list_cb, list); 1309384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1310742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_free(list); 1311384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return NULL; 1312384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1313384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1314ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay h->rule_cache = list; 1315384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1317384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1318384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_save(struct nft_handle *h, const char *table, bool counters) 1319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1320742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 1321742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list_iter *iter; 1322742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 1325b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1328742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_rule_list_iter_create(list); 1329b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1332742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_list_iter_next(iter); 1333384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 1334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 1335742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_str(r, NFTNL_RULE_TABLE); 1336cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka struct iptables_command_state cs = {}; 1337384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1338384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0) 1339384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1340384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1341cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_to_iptables_command_state(r, &cs); 1342cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 1343cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_print_save(&cs, r, NFT_RULE_APPEND, 1344cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka counters ? 0 : FMT_NOCOUNTS); 1345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1347742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_list_iter_next(iter); 1348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1350742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_iter_destroy(iter); 1351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1352384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1354384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain) 1358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1359742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1361742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_alloc(); 1362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) 1363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1364384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1365742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set(r, NFTNL_RULE_TABLE, (char *)table); 1366742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set(r, NFTNL_RULE_CHAIN, (char *)chain); 1367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1368495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso if (batch_rule_add(h, NFT_COMPAT_RULE_FLUSH, r) < 0) 1369742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_free(r); 1370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) 1373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1375742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list; 1376742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 1377742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 1378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_flush; 1380384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1381742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_chain_list_get(h); 1382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1384384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1385384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1387742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 1388b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1389b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 1390384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1391742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 1392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1394742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); 1395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1396742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); 1397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1399384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1402384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1403384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1404384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __nft_rule_flush(h, table_name, chain_name); 1405384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 140636ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 140736ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 1408384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1409742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 1410384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1411384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1412742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 1413ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 1414384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1415742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(list); 1416384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1417384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1419384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table) 1422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1423742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 1424384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14267bc5f6c133bf38c696dc8c14cb479167711437c2Ana Rey nft_fn = nft_chain_user_add; 14277bc5f6c133bf38c696dc8c14cb479167711437c2Ana Rey 1428e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 14298b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 14303599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso nft_xt_builtin_init(h, table); 1431e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 1432742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_alloc(); 1433b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (c == NULL) 1434b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return 0; 1435384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1436742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table); 1437742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)chain); 1438384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14391d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso if (h->batch_support) { 14401d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); 14411d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso } else { 14421d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 14431d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso struct nlmsghdr *nlh; 1444384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1445742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, 14461d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso h->family, 14471d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 1448742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_nlmsg_build_payload(nlh, c); 1449742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_free(c); 14501d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 14511d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso } 1452384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1453384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1454384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1455384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1456384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1457742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int __nft_chain_del(struct nft_handle *h, struct nftnl_chain *c) 1458384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1459384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1460384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1461384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1462742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_DELCHAIN, h->family, 1463384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 1464742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_nlmsg_build_payload(nlh, c); 1465384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14662e256aa818ba5ddf13a4e85f071ef1bf3c485558Tomasz Bursztyka return mnl_talk(h, nlh, NULL, NULL); 1467384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1468384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1469384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table) 1470384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1471742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list; 1472742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 1473742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 1474384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 1475384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int deleted_ctr = 0; 1476384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1477742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_chain_list_get(h); 1478384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1479384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1481742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 1482b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1483b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 1484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1485742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 1486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1488742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); 1489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1490742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); 1491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1492384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* don't delete built-in chain */ 1493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_builtin(c)) 1494384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1495384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1496384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1497384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1498384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1499384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1500384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1501384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 15021d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso if (h->batch_support) 15031d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c); 15041d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso else 15051d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = __nft_chain_del(h, c); 15061d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso 1507384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1508384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1509384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1510384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso deleted_ctr++; 151136ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo 151236ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 151336ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 1514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1515742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 1516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1518742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 1519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 15201d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso if (!h->batch_support) 1521742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(list); 1522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* chain not found */ 15241d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso if (deleted_ctr == 0) { 15251d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = -1; 1526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 15271d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso } 1528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1530384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1532384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1533742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostruct nftnl_chain * 1534742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusonft_chain_list_find(struct nftnl_chain_list *list, 15350aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso const char *table, const char *chain) 15369c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso{ 1537742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 1538742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 15399c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 1540742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 1541b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 15429c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return NULL; 15439c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 1544742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 15459c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso while (c != NULL) { 15469c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso const char *table_name = 1547742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); 15489c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso const char *chain_name = 1549742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); 15509c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 15519c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 15529c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso goto next; 15539c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 15549c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (strcmp(chain, chain_name) != 0) 15559c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso goto next; 15569c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 1557742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 15589c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return c; 15599c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayusonext: 1560742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 15619c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso } 1562742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 15639c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return NULL; 15649c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso} 15659c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 1566742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_chain * 15670aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusonft_chain_find(struct nft_handle *h, const char *table, const char *chain) 15680aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso{ 1569742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list; 15700aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1571742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_chain_list_get(h); 1572b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 15730aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return NULL; 15740aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1575e127d223d01aaa0886c7f279110ac36651b9a057Tomasz Bursztyka return nft_chain_list_find(list, table, chain); 15760aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso} 15770aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_rename(struct nft_handle *h,const char *chain, 1579384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, const char *newname) 1580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1581742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 15829c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso uint64_t handle; 1583384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1584384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1585d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero nft_fn = nft_chain_user_add; 1586d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero 15874493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka /* If built-in chains don't exist for this table, create them */ 15888b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 15893599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso nft_xt_builtin_init(h, table); 15904493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 1591d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero /* Config load changed errno. Ensure genuine info for our callers. */ 1592d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero errno = 0; 1593d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero 15949c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso /* Find the old chain to be renamed */ 15959c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso c = nft_chain_find(h, table, chain); 15969c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (c == NULL) { 15979c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso errno = ENOENT; 15989c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return -1; 15999c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso } 1600742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso handle = nftnl_chain_get_u64(c, NFTNL_CHAIN_HANDLE); 16019c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 16029c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso /* Now prepare the new name for the chain */ 1603742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_alloc(); 1604b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (c == NULL) 16054493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka return -1; 16064493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 1607742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table); 1608742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)newname); 1609742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u64(c, NFTNL_CHAIN_HANDLE, handle); 1610384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 16111d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso if (h->batch_support) { 1612d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero ret = batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c); 16131d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso } else { 16141d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 16151d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso struct nlmsghdr *nlh; 16164493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 1617742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, 16181d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso h->family, NLM_F_ACK, h->seq); 1619742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_nlmsg_build_payload(nlh, c); 1620742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_free(c); 16211d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso 16221d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 16231d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso } 16244493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 16254493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka /* the core expects 1 for success and 0 for error */ 16264493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka return ret == 0 ? 1 : 0; 1627384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1628384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1629742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data) 1630384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1631742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *t; 1632742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list *list = data; 1633384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1634742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso t = nftnl_table_alloc(); 1635cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (t == NULL) 1636384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1637384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1638742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso if (nftnl_table_nlmsg_parse(nlh, t) < 0) 1639384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1640384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1641742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_list_add_tail(t, list); 1642384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1643384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1644384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1645742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_free(t); 1646384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1647384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1648384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1649384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1650742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h) 1651384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1654742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list *list; 1655384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1656742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_table_list_alloc(); 1657b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1658384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1659384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1660742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family, 1661384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1662384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1663742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_talk(h, nlh, nftnl_table_list_cb, list); 1664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1665384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1666384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1667384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1668384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusobool nft_table_find(struct nft_handle *h, const char *tablename) 1669384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1670742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list *list; 1671742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list_iter *iter; 1672742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *t; 1673384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool ret = false; 1674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1675742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_table_list_get(h); 1676384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1678384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1679742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_table_list_iter_create(list); 1680b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1681384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1682384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1683742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso t = nftnl_table_list_iter_next(iter); 1684384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1685384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *this_tablename = 1686742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_get(t, NFTNL_TABLE_NAME); 1687384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1688384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(tablename, this_tablename) == 0) 1689384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1690384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1691742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso t = nftnl_table_list_iter_next(iter); 1692384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1693384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1694742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_list_free(list); 1695384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1696384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1700384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_for_each_table(struct nft_handle *h, 1701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int (*func)(struct nft_handle *h, const char *tablename, bool counters), 1702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool counters) 1703384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 1; 1705742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list *list; 1706742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list_iter *iter; 1707742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *t; 1708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1709742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_table_list_get(h); 1710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1715742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_table_list_iter_create(list); 1716b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1717384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1719742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso t = nftnl_table_list_iter_next(iter); 1720384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1721384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *tablename = 1722742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_get(t, NFTNL_TABLE_NAME); 1723384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1724384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso func(h, tablename, counters); 1725384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1726742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso t = nftnl_table_list_iter_next(iter); 1727384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1728384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1729742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_list_free(list); 1730384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1731384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1733384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1734384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1735384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 17360aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusoint nft_table_purge_chains(struct nft_handle *h, const char *this_table, 1737742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *chain_list) 17380aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso{ 1739742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 1740742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *chain_obj; 17410aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1742742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(chain_list); 1743b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 17440aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return 0; 17450aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1746742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso chain_obj = nftnl_chain_list_iter_next(iter); 17470aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso while (chain_obj != NULL) { 17480aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso const char *table = 1749742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(chain_obj, NFTNL_CHAIN_TABLE); 17500aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 17510aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (strcmp(this_table, table) != 0) 17520aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso goto next; 17530aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 17540aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (nft_chain_builtin(chain_obj)) 17550aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso goto next; 17560aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 17570aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if ( __nft_chain_del(h, chain_obj) < 0) { 17580aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (errno != EBUSY) 17590aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return -1; 17600aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso } 17610aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusonext: 1762742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso chain_obj = nftnl_chain_list_iter_next(iter); 17630aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso } 1764742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 17650aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 17660aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return 0; 17670aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso} 17680aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1769742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic int __nft_rule_del(struct nft_handle *h, struct nftnl_rule_list *list, 1770742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r) 1771384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1772384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1773384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1774742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_del(r); 1775384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1776495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso ret = batch_rule_add(h, NFT_COMPAT_RULE_DELETE, r); 1777d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret < 0) { 1778742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_free(r); 1779d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 1780d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 1781d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 1; 1782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1783384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1784742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusostatic struct nftnl_rule * 1785742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusonft_rule_find(struct nft_handle *h, struct nftnl_rule_list *list, 1786e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso const char *chain, const char *table, void *data, int rulenum) 17873aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso{ 1788742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1789742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list_iter *iter; 17903aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int rule_ctr = 0; 17913aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso bool found = false; 17923aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1793742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_rule_list_iter_create(list); 1794b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1795384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1796384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1797742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_list_iter_next(iter); 1798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 1799384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 1800742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_str(r, NFTNL_RULE_TABLE); 1801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 1802742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); 1803384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 1805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) { 1806384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different chain / table\n"); 1807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1810384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (rulenum >= 0) { 1811384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete by rule number case */ 181234344db9878ed53b387180362b1be77001e03e45Thomas Woerner if (rule_ctr == rulenum) { 181334344db9878ed53b387180362b1be77001e03e45Thomas Woerner found = true; 181434344db9878ed53b387180362b1be77001e03e45Thomas Woerner break; 181534344db9878ed53b387180362b1be77001e03e45Thomas Woerner } 1816384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 1817e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso found = h->ops->rule_find(h->ops, r, data); 1818e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso if (found) 1819e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso break; 1820384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 18214acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka rule_ctr++; 182234344db9878ed53b387180362b1be77001e03e45Thomas Woernernext: 1823742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_list_iter_next(iter); 1824384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1825384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1826742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_iter_destroy(iter); 1827384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 18283aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return found ? r : NULL; 1829384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1830384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1831384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_check(struct nft_handle *h, const char *chain, 1832b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, bool verbose) 1833384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1834742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 18353aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret; 18363aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1837384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_check; 1838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 18392abd049177fa42993e4b1de588e92282a200ee43Pablo M. Bermudo Garay list = nft_rule_list_get(h); 1840b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 18413aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 18423aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1843b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso ret = nft_rule_find(h, list, chain, table, data, -1) ? 1 : 0; 18443aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (ret == 0) 18453aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 18463aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 18473aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 1848384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1850384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete(struct nft_handle *h, const char *chain, 1851b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, bool verbose) 1852384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 18533aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 1854742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1855742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 18563aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1857384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete; 1858384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 18592abd049177fa42993e4b1de588e92282a200ee43Pablo M. Bermudo Garay list = nft_rule_list_get(h); 1860b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 18613aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 18623aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1863b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_find(h, list, chain, table, data, -1); 18643aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 1865d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret =__nft_rule_del(h, list, r); 1866d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret < 0) 1867d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso errno = ENOMEM; 18683aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 18693aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 18703aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1871ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 18723aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 18733aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 1874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1876cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusostatic int 1877cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusonft_rule_add(struct nft_handle *h, const char *chain, 1878cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso const char *table, struct iptables_command_state *cs, 1879cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso uint64_t handle, bool verbose) 1880cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso{ 1881742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1882cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1883cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso r = nft_rule_new(h, chain, table, cs); 1884d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (r == NULL) 1885d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 1886d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 188766a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (handle > 0) 1888742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle); 1889cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1890495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso if (batch_rule_add(h, NFT_COMPAT_RULE_INSERT, r) < 0) { 1891742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_free(r); 1892d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 1893cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso } 1894cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1895ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 1896d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 1; 1897cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso} 1898cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1899cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoint nft_rule_insert(struct nft_handle *h, const char *chain, 1900b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, int rulenum, bool verbose) 1901cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso{ 1902742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 1903742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 190466a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso uint64_t handle = 0; 1905cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1906cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 1907cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 19083599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso nft_xt_builtin_init(h, table); 1909cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1910cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_fn = nft_rule_insert; 1911cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 191266a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (rulenum > 0) { 19132abd049177fa42993e4b1de588e92282a200ee43Pablo M. Bermudo Garay list = nft_rule_list_get(h); 191466a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (list == NULL) 191566a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso goto err; 1916cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1917b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_find(h, list, chain, table, data, rulenum); 191866a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (r == NULL) { 19198e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner /* special case: iptables allows to insert into 19208e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner * rule_count + 1 position. 19218e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner */ 19228e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner r = nft_rule_find(h, list, chain, table, data, 19238e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner rulenum - 1); 19248e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner if (r != NULL) { 1925ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 19268e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner return nft_rule_append(h, chain, table, data, 19278e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner 0, verbose); 19288e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner } 19298e1522698a7495002e5154f5643abb68e9c3a89aThomas Woerner 193066a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso errno = ENOENT; 193166a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso goto err; 193266a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso } 1933cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1934742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso handle = nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE); 193566a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso DEBUGP("adding after rule handle %"PRIu64"\n", handle); 1936cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1937ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 1938cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso } 1939cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1940b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso return nft_rule_add(h, chain, table, data, handle, verbose); 1941cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoerr: 1942ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 1943cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return 0; 1944cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso} 1945cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1946384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete_num(struct nft_handle *h, const char *chain, 19473aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso const char *table, int rulenum, bool verbose) 1948384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 19493aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 1950742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1951742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 19523aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1953384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete_num; 1954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 19552abd049177fa42993e4b1de588e92282a200ee43Pablo M. Bermudo Garay list = nft_rule_list_get(h); 1956b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 19573aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 19583aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1959e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso r = nft_rule_find(h, list, chain, table, NULL, rulenum); 19603aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 19613aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso ret = 1; 19623aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 19633aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso DEBUGP("deleting rule by number %d\n", rulenum); 1964d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = __nft_rule_del(h, list, r); 1965d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret < 0) 1966d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso errno = ENOMEM; 19673aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 19683aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 19693aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1970ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 19713aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 19723aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 1973384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1974384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1975384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_replace(struct nft_handle *h, const char *chain, 1976b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, int rulenum, bool verbose) 1977384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 19783aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 1979742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 1980742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 1981384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1982384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_replace; 1983384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 19842abd049177fa42993e4b1de588e92282a200ee43Pablo M. Bermudo Garay list = nft_rule_list_get(h); 1985b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 19863aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 19873aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1988b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_find(h, list, chain, table, data, rulenum); 19893aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 19901298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso DEBUGP("replacing rule with handle=%llu\n", 19911298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso (unsigned long long) 1992742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE)); 1993384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1994b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso ret = nft_rule_append(h, chain, table, data, 1995742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE), 1996cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso verbose); 19973aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 19983aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 19993aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 2000ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 20013aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 20023aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 2003384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2004384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2005384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 2006b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka__nft_rule_list(struct nft_handle *h, const char *chain, const char *table, 2007384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format, 2008742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso void (*cb)(struct nftnl_rule *r, unsigned int num, 2009384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int format)) 2010384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2011742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 2012742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list_iter *iter; 2013742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 2014384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rule_ctr = 0, ret = 0; 2015384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2016384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 2017b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 2018384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2019384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2020742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_rule_list_iter_create(list); 2021b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2022b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2023384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2024742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_list_iter_next(iter); 2025384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 2026384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 2027742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_str(r, NFTNL_RULE_TABLE); 2028384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 2029742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); 2030384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2031384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 2032384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) 2033384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2034384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 203534344db9878ed53b387180362b1be77001e03e45Thomas Woerner rule_ctr++; 203634344db9878ed53b387180362b1be77001e03e45Thomas Woerner 20370b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo if (rulenum > 0 && rule_ctr != rulenum) { 2038384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* List by rule number case */ 20390b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo goto next; 20400b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo } 2041384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 20428aa384a7d54734fd830840a2593cd4f07749976fTomasz Bursztyka cb(r, rule_ctr, format); 20430b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo if (rulenum > 0 && rule_ctr == rulenum) { 20440b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo ret = 1; 20450b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo break; 2046384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 20470b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo 2048384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2049742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso r = nftnl_rule_list_iter_next(iter); 2050384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2051384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2052742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_iter_destroy(iter); 2053b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2054384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == 0) 2055384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 2056384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2057384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 2058384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2059384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2060384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list(struct nft_handle *h, const char *chain, const char *table, 2061384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format) 2062384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2063e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka const struct nft_family_ops *ops; 2064742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list; 2065742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 2066742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 20670a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo bool found = false; 2068384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2069aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka /* If built-in chains don't exist for this table, create them */ 2070a4e78370af8498e2de65fcb8aafed39a4482966cPablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) { 20713599c617f6509d120dfddf78a024bdd32633cf2dPablo Neira Ayuso nft_xt_builtin_init(h, table); 2072a4e78370af8498e2de65fcb8aafed39a4482966cPablo Neira Ayuso /* Force table and chain creation, otherwise first iptables -L 2073a4e78370af8498e2de65fcb8aafed39a4482966cPablo Neira Ayuso * lists no table/chains. 2074a4e78370af8498e2de65fcb8aafed39a4482966cPablo Neira Ayuso */ 2075a4e78370af8498e2de65fcb8aafed39a4482966cPablo Neira Ayuso if (!list_empty(&h->obj_list)) 2076a4e78370af8498e2de65fcb8aafed39a4482966cPablo Neira Ayuso nft_commit(h); 2077a4e78370af8498e2de65fcb8aafed39a4482966cPablo Neira Ayuso } 2078aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka 2079e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka ops = nft_family_ops_lookup(h->family); 2080e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka 2081b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka if (chain && rulenum) { 2082b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka __nft_rule_list(h, chain, table, 2083e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka rulenum, format, ops->print_firewall); 2084b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka return 1; 2085b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka } 2086b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka 2087384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2088384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2089742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 2090b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2091b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2092384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 209351e83a4deb4849152a29c160893f0823846d47a0Giuseppe Longo if (ops->print_table_header) 209451e83a4deb4849152a29c160893f0823846d47a0Giuseppe Longo ops->print_table_header(table); 209551e83a4deb4849152a29c160893f0823846d47a0Giuseppe Longo 2096742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2097384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2098384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2099742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); 2100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2101742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); 2102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2103742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); 2104384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t refs = 2105742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_u32(c, NFTNL_CHAIN_USE); 2106384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_counters ctrs = { 2107742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), 2108742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES), 2109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 2111384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2112742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM)) 2113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso basechain = true; 2114384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2115384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2116384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2117384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 21200a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo if (found) 21210a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf("\n"); 21220a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 21234272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso ops->print_header(format, chain_name, policy_name[policy], 21244272426912b0951b4dc7f40179d5217b513775e1Pablo Neira Ayuso &ctrs, basechain, refs); 21257a1026f59c101a67233c65dd5ef9b0ae15945ca5Tomasz Bursztyka 2126b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka __nft_rule_list(h, chain_name, table, 2127e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka rulenum, format, ops->print_firewall); 21280a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 2129da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso /* we printed the chain we wanted, stop processing. */ 2130da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso if (chain) 2131da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso break; 2132da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso 21330a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo found = true; 21340a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 2135384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2136742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2137384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2138384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2139742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 2140b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2141742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(list); 2142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2143384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2144384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2145384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2146384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 2147742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusolist_save(struct nftnl_rule *r, unsigned int num, unsigned int format) 2148384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2149cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka struct iptables_command_state cs = {}; 2150cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 2151cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_to_iptables_command_state(r, &cs); 2152cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 2153cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_print_save(&cs, r, NFT_RULE_APPEND, !(format & FMT_NOCOUNTS)); 2154384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2155384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2156384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 2157742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayusonftnl_rule_list_chain_save(struct nft_handle *h, const char *chain, 2158742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso const char *table, struct nftnl_chain_list *list, 21598dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso int counters) 2160384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2161742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 2162742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 2163384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2164742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 2165b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2166384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2167384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2168742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2169384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2170384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2171742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); 2172384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2173742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); 2174384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2175742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); 2176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 21778dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso if (strcmp(table, chain_table) != 0 || 21788dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso (chain && strcmp(chain, chain_name) != 0)) 2179384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2180384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2181384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* this is a base chain */ 21827244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka if (nft_chain_builtin(c)) { 2183384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-P %s %s", chain_name, policy_name[policy]); 2184384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2185384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 21860a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(" -c %"PRIu64" %"PRIu64"\n", 2187742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), 2188742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES)); 2189384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2190384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 2191384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2192384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-N %s\n", chain_name); 2193384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2194384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2195742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2196384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2197384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2198742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 2199e9a0ef8f1e27f5ef13a27f6cc984e8f2e05afd72Tomasz Bursztyka 2200384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2201384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2202384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2203384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list_save(struct nft_handle *h, const char *chain, 2204384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, int rulenum, int counters) 2205384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2206742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list; 2207742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 2208742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 220910f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso int ret = 1; 2210384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Dump policies and custom chains first */ 221410f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso if (!rulenum) 2215742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_list_chain_save(h, chain, table, list, counters); 2216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Now dump out rules in this table */ 2218742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 2219b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2220b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2221384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2222742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2223384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2224384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2225742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); 2226384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2227742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); 2228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2229384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2230384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2231384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2232384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2233384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2234b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka ret = __nft_rule_list(h, chain_name, table, rulenum, 223510f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso counters ? 0 : FMT_NOCOUNTS, list_save); 2236da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso 2237da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso /* we printed the chain we wanted, stop processing. */ 2238da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso if (chain) 2239da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso break; 2240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2241742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2242384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2243e9a0ef8f1e27f5ef13a27f6cc984e8f2e05afd72Tomasz Bursztyka 2244742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 2245b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2246742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(list); 2247384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 224810f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso return ret; 2249384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2250384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2251a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztykaint nft_rule_zero_counters(struct nft_handle *h, const char *chain, 2252a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka const char *table, int rulenum) 2253a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka{ 2254a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka struct iptables_command_state cs = {}; 2255742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule_list *list; 2256742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *r; 2257a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka int ret = 0; 2258a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2259a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka nft_fn = nft_rule_delete; 2260a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 22612abd049177fa42993e4b1de588e92282a200ee43Pablo M. Bermudo Garay list = nft_rule_list_get(h); 2262a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka if (list == NULL) 2263a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka return 0; 2264a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2265e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso r = nft_rule_find(h, list, chain, table, NULL, rulenum); 2266a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka if (r == NULL) { 2267a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka errno = ENOENT; 2268a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka ret = 1; 2269a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka goto error; 2270a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka } 2271a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2272a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka nft_rule_to_iptables_command_state(r, &cs); 2273a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2274a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka cs.counters.pcnt = cs.counters.bcnt = 0; 2275a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2276a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka ret = nft_rule_append(h, chain, table, &cs, 2277742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE), 2278a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka false); 2279a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2280a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztykaerror: 2281ef2a7e9fe0d82c691aeee1cbd61095841231974fPablo M. Bermudo Garay flush_rule_cache(h); 2282a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2283a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka return ret; 2284a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka} 2285a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2286f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic void nft_compat_table_batch_add(struct nft_handle *h, uint16_t type, 2287f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso uint16_t flags, uint32_t seq, 2288742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *table) 2289f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 2290f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso struct nlmsghdr *nlh; 2291f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 2292742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_table_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch), 2293f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso type, h->family, flags, seq); 2294742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_nlmsg_build_payload(nlh, table); 2295742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_free(table); 2296f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 2297f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 2298f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic void nft_compat_chain_batch_add(struct nft_handle *h, uint16_t type, 2299f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso uint16_t flags, uint32_t seq, 2300742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *chain) 2301f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 2302f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso struct nlmsghdr *nlh; 2303f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 2304742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_chain_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch), 2305f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso type, h->family, flags, seq); 2306742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_nlmsg_build_payload(nlh, chain); 2307f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_chain_print_debug(chain, nlh); 2308742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_free(chain); 2309f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 2310f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 2311f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayusostatic void nft_compat_rule_batch_add(struct nft_handle *h, uint16_t type, 2312f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso uint16_t flags, uint32_t seq, 2313742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_rule *rule) 2314f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso{ 2315f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso struct nlmsghdr *nlh; 2316f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 2317742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch), 2318f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso type, h->family, flags, seq); 2319742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_nlmsg_build_payload(nlh, rule); 2320f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_rule_print_debug(rule, nlh); 2321742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_rule_free(rule); 2322f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso} 2323f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso 2324d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int nft_action(struct nft_handle *h, int action) 23259e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 2326495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso struct obj_update *n, *tmp; 2327d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso uint32_t seq = 1; 2328f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso int ret = 0; 23299e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2330742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_nftnl_batch_begin(h->batch, seq++); 23319e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2332495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso list_for_each_entry_safe(n, tmp, &h->obj_list, head) { 2333d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso switch (n->type) { 2334f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso case NFT_COMPAT_TABLE_ADD: 2335f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_compat_table_batch_add(h, NFT_MSG_NEWTABLE, 2336f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_CREATE, seq++, 2337f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso n->table); 2338f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso break; 2339f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso case NFT_COMPAT_CHAIN_ADD: 2340f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN, 2341f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_CREATE, seq++, 2342f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso n->chain); 2343f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso break; 23441d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso case NFT_COMPAT_CHAIN_USER_ADD: 23451d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN, 23461d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso NLM_F_EXCL, seq++, 23471d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso n->chain); 23481d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso break; 23491d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso case NFT_COMPAT_CHAIN_USER_DEL: 23501d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso nft_compat_chain_batch_add(h, NFT_MSG_DELCHAIN, 23511d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso 0, seq++, n->chain); 23521d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso break; 2353f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso case NFT_COMPAT_CHAIN_UPDATE: 2354f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN, 2355f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso h->restore ? 2356f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_CREATE : 0, 2357f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso seq++, n->chain); 2358f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso break; 2359d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero case NFT_COMPAT_CHAIN_RENAME: 2360d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN, 0, 2361d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero seq++, n->chain); 2362d87b76cfc3b1c003fec75b8a4ea639aa444014f3Arturo Borrero break; 2363495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso case NFT_COMPAT_RULE_APPEND: 2364f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_compat_rule_batch_add(h, NFT_MSG_NEWRULE, 2365f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_CREATE | NLM_F_APPEND, 2366f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso seq++, n->rule); 2367d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2368495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso case NFT_COMPAT_RULE_INSERT: 2369f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_compat_rule_batch_add(h, NFT_MSG_NEWRULE, 2370f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_CREATE, seq++, 2371f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso n->rule); 2372d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2373495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso case NFT_COMPAT_RULE_REPLACE: 2374f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_compat_rule_batch_add(h, NFT_MSG_NEWRULE, 2375f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso NLM_F_CREATE | NLM_F_REPLACE, 2376f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso seq++, n->rule); 2377d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2378495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso case NFT_COMPAT_RULE_DELETE: 2379495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso case NFT_COMPAT_RULE_FLUSH: 2380f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso nft_compat_rule_batch_add(h, NFT_MSG_DELRULE, 0, 2381f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso seq++, n->rule); 2382d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2383d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 23849e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2385495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso h->obj_list_num--; 2386d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso list_del(&n->head); 2387d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso free(n); 2388d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2389d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (!mnl_nlmsg_batch_next(h->batch)) 2390742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso h->batch = mnl_nftnl_batch_page_add(h->batch); 2391d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 2392d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2393d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso switch (action) { 2394495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso case NFT_COMPAT_COMMIT: 2395742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso mnl_nftnl_batch_end(h->batch, seq++); 2396d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2397495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso case NFT_COMPAT_ABORT: 2398d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 23999e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 2400d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2401d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (!mnl_nlmsg_batch_is_empty(h->batch)) 2402742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso h->batch = mnl_nftnl_batch_page_add(h->batch); 2403d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2404742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso ret = mnl_nftnl_batch_talk(h); 2405d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2406d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_batch_reset(h->batch); 2407d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2408f041efe3c26e3059df1ac8f1775f77423d4be5f6Pablo Neira Ayuso return ret == 0 ? 1 : 0; 24099e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 24109e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 24119e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayusoint nft_commit(struct nft_handle *h) 24129e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 2413495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso return nft_action(h, NFT_COMPAT_COMMIT); 24149e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 24159e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 24169e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayusoint nft_abort(struct nft_handle *h) 24179e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 2418495f1e8cc1753a3577a0b6c790b96b34859cd9bdPablo Neira Ayuso return nft_action(h, NFT_COMPAT_ABORT); 24199e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 24209e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_compatible_revision(const char *name, uint8_t rev, int opt) 2422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct mnl_socket *nl; 2424384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 2425384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 2426384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t portid, seq, type; 2427384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 2428384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 242985512f09680a798ebe92e96ad62eeae863fbc791Pablo Neira Ayuso if (opt == IPT_SO_GET_REVISION_MATCH || 243085512f09680a798ebe92e96ad62eeae863fbc791Pablo Neira Ayuso opt == IP6T_SO_GET_REVISION_MATCH) 2431384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 0; 2432384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2433384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 1; 2434384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2435384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = mnl_nlmsg_put_header(buf); 2436384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET; 2437384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 2438384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_seq = seq = time(NULL); 2439384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2440384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); 2441384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->nfgen_family = AF_INET; 2442384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->version = NFNETLINK_V0; 2443384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->res_id = 0; 2444384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2445384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_strz(nlh, NFTA_COMPAT_NAME, name); 2446384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_REV, htonl(rev)); 2447384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_TYPE, htonl(type)); 2448384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2449384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("requesting `%s' rev=%d type=%d via nft_compat\n", 2450384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name, rev, type); 2451384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2452384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nl = mnl_socket_open(NETLINK_NETFILTER); 2453cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (nl == NULL) 2454384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2455384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2456cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) 2457384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2458cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso 2459384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso portid = mnl_socket_get_portid(nl); 2460384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2461cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) 2462384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2463384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2464384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); 2465cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (ret == -1) 2466384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2467384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2468384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); 2469cbe036db892c298c33e77dec2c5129dbb4dccc2cPablo Neira Ayuso if (ret == -1) 2470384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2471384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2472384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 2473384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(nl); 2474384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2475384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret < 0 ? 0 : 1; 2476384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2477384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2478384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* Translates errno numbers into more human-readable form than strerror. */ 2479384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoconst char *nft_strerror(int err) 2480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int i; 2482384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso static struct table_struct { 2483384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *fn; 2484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int err; 2485384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *message; 2486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } table[] = 2487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { 2488384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, ENOTEMPTY, "Chain is not empty" }, 2489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EINVAL, "Can't delete built-in chain" }, 24907bc5f6c133bf38c696dc8c14cb479167711437c2Ana Rey { nft_chain_user_del, EBUSY, "Directory not empty" }, 2491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EMLINK, 2492384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Can't delete chain with references left" }, 2493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_add, EEXIST, "Chain already exists" }, 2494384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, E2BIG, "Index of insertion too big" }, 24957bc5f6c133bf38c696dc8c14cb479167711437c2Ana Rey { nft_rule_check, ENOENT, "Bad rule (does a matching rule exist in that chain?)" }, 2496b92426faab5101bc250832fca85ee8fa3548572dAna Rey { nft_rule_replace, ENOENT, "Index of replacement too big" }, 2497384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete_num, E2BIG, "Index of deletion too big" }, 2498384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* { TC_READ_COUNTER, E2BIG, "Index of counter too big" }, 2499384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */ 2500384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, ELOOP, "Loop found in table" }, 2501384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, EINVAL, "Target problem" }, 2502384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* ENOENT for DELETE probably means no matching rule */ 2503384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete, ENOENT, 2504384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Bad rule (does a matching rule exist in that chain?)" }, 2505384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, ENOENT, "Bad built-in chain name" }, 2506384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, EINVAL, "Bad policy name" }, 2507384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, EPERM, "Permission denied (you must be root)" }, 2508384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, 0, "Incompatible with this kernel" }, 2509384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" }, 2510384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOSYS, "Will be implemented real soon. I promise ;)" }, 2511384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOMEM, "Memory allocation problem" }, 2512384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOENT, "No chain/target/match by that name" }, 2513384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2515384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) { 2516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if ((!table[i].fn || table[i].fn == nft_fn) 2517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso && table[i].err == err) 2518384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return table[i].message; 2519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2520384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2521384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return strerror(err); 2522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 25238b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 25248b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayusostatic void xtables_config_perror(uint32_t flags, const char *fmt, ...) 25258b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso{ 25268b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_list args; 25278b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 25288b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_start(args, fmt); 25298b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 25308b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (flags & NFT_LOAD_VERBOSE) 25318b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso vfprintf(stderr, fmt, args); 25328b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 25338b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_end(args); 25348b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso} 25358b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 25368b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayusoint nft_xtables_config_load(struct nft_handle *h, const char *filename, 25378b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso uint32_t flags) 25388b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso{ 2539742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list *table_list = nftnl_table_list_alloc(); 2540742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *chain_list = nftnl_chain_list_alloc(); 2541742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table_list_iter *titer = NULL; 2542742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *citer = NULL; 2543742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_table *table; 2544742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *chain; 2545cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo uint32_t table_family, chain_family; 2546cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo bool found = false; 25478b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 2548e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka if (h->restore) 2549e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka return 0; 2550e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka 25518b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (xtables_config_parse(filename, table_list, chain_list) < 0) { 25528b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == ENOENT) { 25538b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 25548b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "configuration file `%s' does not exists\n", 25558b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso filename); 25568b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 25578b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 25588b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "Fatal error parsing config file: %s\n", 25598b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 25608b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 25616a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 25628b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 25638b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 25648b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso /* Stage 1) create tables */ 2565742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso titer = nftnl_table_list_iter_create(table_list); 2566742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso while ((table = nftnl_table_list_iter_next(titer)) != NULL) { 2567742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso table_family = nftnl_table_get_u32(table, 2568742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso NFTNL_TABLE_FAMILY); 2569cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo if (h->family != table_family) 2570cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo continue; 2571cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 2572cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo found = true; 2573cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 2574f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (batch_table_add(h, NFT_COMPAT_TABLE_ADD, table) < 0) { 25758b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == EEXIST) { 25768b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 25778b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "table `%s' already exists, skipping\n", 2578742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_table_get(table, NFTNL_TABLE_NAME)); 25798b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 25808b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 25818b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "table `%s' cannot be create, reason `%s'. Exitting\n", 2582742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_table_get(table, NFTNL_TABLE_NAME), 25838b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 25846a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 25858b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 25868b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso continue; 25878b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 25888b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, "table `%s' has been created\n", 2589742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_table_get(table, NFTNL_TABLE_NAME)); 25908b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 2591742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_list_iter_destroy(titer); 2592742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_list_free(table_list); 25938b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 2594cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo if (!found) 25956a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 2596cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 25978b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso /* Stage 2) create chains */ 2598742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso citer = nftnl_chain_list_iter_create(chain_list); 2599742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso while ((chain = nftnl_chain_list_iter_next(citer)) != NULL) { 2600742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso chain_family = nftnl_chain_get_u32(chain, 2601742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso NFTNL_CHAIN_TABLE); 2602cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo if (h->family != chain_family) 2603cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo continue; 2604cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 2605f1299b98d7ff200eb50ca574278bfeb1368de01bPablo Neira Ayuso if (batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, chain) < 0) { 26068b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == EEXIST) { 26078b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 26088b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' already exists in table `%s', skipping\n", 2609742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_chain_get(chain, NFTNL_CHAIN_NAME), 2610742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_chain_get(chain, NFTNL_CHAIN_TABLE)); 26118b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 26128b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 26138b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' cannot be create, reason `%s'. Exitting\n", 2614742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_chain_get(chain, NFTNL_CHAIN_NAME), 26158b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 26166a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 26178b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 26188b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso continue; 26198b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 26208b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 26218b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 26228b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' in table `%s' has been created\n", 2623742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_chain_get(chain, NFTNL_CHAIN_NAME), 2624742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso (char *)nftnl_chain_get(chain, NFTNL_CHAIN_TABLE)); 26258b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 2626742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(citer); 2627742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(chain_list); 26282c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso 26298b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso return 0; 26306a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey 26316a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Reyerr: 2632742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_list_free(table_list); 2633742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(chain_list); 26346a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey 26356a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey if (titer != NULL) 2636742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_table_list_iter_destroy(titer); 26376a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey if (citer != NULL) 2638742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(citer); 26396a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey 26406a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey return -1; 26418b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso} 2642b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2643b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longoint nft_chain_zero_counters(struct nft_handle *h, const char *chain, 2644b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *table) 2645b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo{ 2646742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list *list; 2647742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain_list_iter *iter; 2648742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso struct nftnl_chain *c; 2649b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo int ret = 0; 2650b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2651742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso list = nftnl_chain_list_get(h); 2652b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (list == NULL) 2653b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto err; 2654b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2655742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso iter = nftnl_chain_list_iter_create(list); 2656b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2657b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2658b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2659742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2660b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo while (c != NULL) { 2661b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *chain_name = 2662742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get(c, NFTNL_CHAIN_NAME); 2663b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *chain_table = 2664742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_get(c, NFTNL_CHAIN_TABLE); 2665b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2666b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (strcmp(table, chain_table) != 0) 2667b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto next; 2668b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2669b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (chain != NULL && strcmp(chain, chain_name) != 0) 2670b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto next; 2671b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2672742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0); 2673742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0); 2674b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2675742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); 2676b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 26771d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso if (h->batch_support) { 26781d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c); 26791d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso } else { 26801d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso struct nlmsghdr *nlh; 26811d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 26821d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso 2683742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, 26841d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso h->family, NLM_F_ACK, 26851d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso h->seq); 2686742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_nlmsg_build_payload(nlh, c); 26871d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 26881d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso } 2689b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 269036ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 269136ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 2692b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longonext: 2693742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso c = nftnl_chain_list_iter_next(iter); 2694b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo } 2695b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 26961d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso if (!h->batch_support) 2697742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_free(list); 26981d395bcb585dd941859f2206eed89da23d19909cPablo Neira Ayuso 2699742baabd185c326cc2125e648e240894362eb31cPablo Neira Ayuso nftnl_chain_list_iter_destroy(iter); 2700b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2701b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longoerr: 2702b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo /* the core expects 1 for success and 0 for error */ 2703b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo return ret == 0 ? 1 : 0; 2704b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo} 2705c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero 2706c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrerouint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag) 2707c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero{ 2708c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero if (invflags & flag) 2709c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero return NFT_CMP_NEQ; 2710c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero 2711c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero return NFT_CMP_EQ; 2712c82bf9f79bbc299de428fdc2e204d571b6cbc50dArturo Borrero} 27134b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27144b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay#define NFT_COMPAT_EXPR_MAX 8 27154b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27164b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaystatic const char *supported_exprs[NFT_COMPAT_EXPR_MAX] = { 27174b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "match", 27184b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "target", 27194b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "payload", 27204b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "meta", 27214b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "cmp", 27224b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "bitwise", 27234b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "counter", 27244b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay "immediate" 27254b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay}; 27264b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27274b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27284b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaystatic int nft_is_expr_compatible(const char *name) 27294b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay{ 27304b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay int i; 27314b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27324b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay for (i = 0; i < NFT_COMPAT_EXPR_MAX; i++) { 27334b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (strcmp(supported_exprs[i], name) == 0) 27344b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return 0; 27354b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 27364b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27374b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return 1; 27384b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay} 27394b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27404b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaystatic int nft_is_rule_compatible(struct nftnl_rule *rule) 27414b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay{ 27424b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_expr_iter *iter; 27434b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_expr *expr; 27444b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay int ret = 0; 27454b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27464b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay iter = nftnl_expr_iter_create(rule); 27474b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (iter == NULL) 27484b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return -1; 27494b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27504b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay expr = nftnl_expr_iter_next(iter); 27514b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay while (expr != NULL) { 27524b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay const char *name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME); 27534b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27544b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (nft_is_expr_compatible(name) == 0) { 27554b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay expr = nftnl_expr_iter_next(iter); 27564b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay continue; 27574b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 27584b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27594b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay ret = 1; 27604b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay break; 27614b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 27624b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27634b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay nftnl_expr_iter_destroy(iter); 27644b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return ret; 27654b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay} 27664b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27674b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaystatic int nft_is_chain_compatible(const char *table, const char *chain) 27684b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay{ 27694b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay const char *cur_table; 27704b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct builtin_chain *chains; 27714b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay int i, j; 27724b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27734b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay for (i = 0; i < TABLES_MAX; i++) { 27744b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay cur_table = xtables_ipv4[i].name; 27754b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay chains = xtables_ipv4[i].chains; 27764b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27774b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (strcmp(table, cur_table) != 0) 27784b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay continue; 27794b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27804b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay for (j = 0; j < NF_INET_NUMHOOKS && chains[j].name; j++) { 27814b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (strcmp(chain, chains[j].name) == 0) 27824b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return 0; 27834b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 27844b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 27854b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27864b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return 1; 27874b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay} 27884b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27894b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaystatic int nft_are_chains_compatible(struct nft_handle *h) 27904b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay{ 27914b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_chain_list *list; 27924b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_chain_list_iter *iter; 27934b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_chain *chain; 27944b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay int ret = 0; 27954b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 27964b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay list = nftnl_chain_list_get(h); 27974b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (list == NULL) 27984b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return -1; 27994b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28004b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay iter = nftnl_chain_list_iter_create(list); 28014b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (iter == NULL) 28024b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return -1; 28034b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28044b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay chain = nftnl_chain_list_iter_next(iter); 28054b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay while (chain != NULL) { 28064b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (!nft_chain_builtin(chain)) 28074b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay goto next; 28084b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28094b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay const char *table = nftnl_chain_get(chain, NFTNL_CHAIN_TABLE); 28104b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay const char *name = nftnl_chain_get(chain, NFTNL_CHAIN_NAME); 28114b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28124b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (nft_is_chain_compatible(table, name) == 1) { 28134b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay ret = 1; 28144b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay break; 28154b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 28164b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28174b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaynext: 28184b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay chain = nftnl_chain_list_iter_next(iter); 28194b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 28204b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28214b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay nftnl_chain_list_iter_destroy(iter); 28224b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay nftnl_chain_list_free(list); 28234b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return ret; 28244b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay} 28254b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28264b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaystatic int nft_is_table_compatible(const char *name) 28274b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay{ 28284b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay int i; 28294b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28304b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay for (i = 0; i < TABLES_MAX; i++) { 28314b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (strcmp(xtables_ipv4[i].name, name) == 0) 28324b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return 0; 28334b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 28344b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28354b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return 1; 28364b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay} 28374b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28384b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garaystatic int nft_are_tables_compatible(struct nft_handle *h) 28394b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay{ 28404b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_table_list *list; 28414b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_table_list_iter *iter; 28424b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_table *table; 28434b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay int ret = 0; 28444b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28454b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay list = nftnl_table_list_get(h); 28464b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (list == NULL) 28474b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return -1; 28484b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28494b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay iter = nftnl_table_list_iter_create(list); 28504b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (iter == NULL) 28514b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return -1; 28524b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28534b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay table = nftnl_table_list_iter_next(iter); 28544b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay while (table != NULL) { 28554b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay const char *name = nftnl_table_get(table, NFTNL_TABLE_NAME); 28564b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28574b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (nft_is_table_compatible(name) == 0) { 28584b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay table = nftnl_table_list_iter_next(iter); 28594b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay continue; 28604b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 28614b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28624b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay ret = 1; 28634b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay break; 28644b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 28654b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28664b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay nftnl_table_list_iter_destroy(iter); 28674b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay nftnl_table_list_free(list); 28684b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return ret; 28694b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay} 28704b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28714b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garayint nft_is_ruleset_compatible(struct nft_handle *h) 28724b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay{ 28734b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28744b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_rule_list *list; 28754b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_rule_list_iter *iter; 28764b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay struct nftnl_rule *rule; 28774b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay int ret = 0; 28784b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28794b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay ret = nft_are_tables_compatible(h); 28804b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (ret != 0) 28814b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return ret; 28824b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28834b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay ret = nft_are_chains_compatible(h); 28844b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (ret != 0) 28854b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return ret; 28864b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28874b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay list = nft_rule_list_get(h); 28884b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (list == NULL) 28894b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return -1; 28904b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28914b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay iter = nftnl_rule_list_iter_create(list); 28924b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (iter == NULL) 28934b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return -1; 28944b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 28954b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay rule = nftnl_rule_list_iter_next(iter); 28964b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay while (rule != NULL) { 28974b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay ret = nft_is_rule_compatible(rule); 28984b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay if (ret != 0) 28994b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay break; 29004b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 29014b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay rule = nftnl_rule_list_iter_next(iter); 29024b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay } 29034b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay 29044b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay nftnl_rule_list_iter_destroy(iter); 29054b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay return ret; 29064b791044cd0984c9a1771e86fa77fce9d309d9e7Pablo M. Bermudo Garay} 2907