nft.c revision e6b8e172fca48f5d80699afe80947b0fc1f23fd6
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> 45384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 46384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <netinet/in.h> /* inet_ntoa */ 47384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include <arpa/inet.h> 48384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 49384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "nft.h" 50384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#include "xshared.h" /* proto_to_name */ 51077785df023ad8947d44d19769bc6d91e3917633Tomasz Bursztyka#include "nft-shared.h" 528b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso#include "xtables-config-parser.h" 53384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 54384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void *nft_fn; 55384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 5684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh, 5784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo int (*cb)(const struct nlmsghdr *nlh, void *data), 5884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo void *data) 59384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 60384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 61384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 62384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 63384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_sendto(h->nl, nlh, nlh->nlmsg_len) < 0) { 64384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_send"); 65384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 66384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 67384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 68384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 69384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (ret > 0) { 70384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_cb_run(buf, ret, h->seq, h->portid, cb, data); 71384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret <= 0) 72384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 73384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 74384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf)); 75384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 76384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 77384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 78384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 79384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 80384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 81384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 82384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 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 97d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic struct mnl_nlmsg_batch *mnl_nft_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 * 110d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusomnl_nft_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 122d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return mnl_nft_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 144d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic ssize_t mnl_nft_socket_sendmsg(const struct mnl_socket *nl) 145d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 146d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso static const struct sockaddr_nl snl = { 147d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .nl_family = AF_NETLINK 148d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso }; 149d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct iovec iov[batch_num_pages]; 150d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct msghdr msg = { 151d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_name = (struct sockaddr *) &snl, 152d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_namelen = sizeof(snl), 153d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_iov = iov, 154d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso .msg_iovlen = batch_num_pages, 155d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso }; 156d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct batch_page *batch_page, *next; 157d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso int i = 0; 158d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 159d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nft_set_sndbuffer(nl); 160d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 161d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso list_for_each_entry_safe(batch_page, next, &batch_page_list, head) { 162d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso iov[i].iov_base = mnl_nlmsg_batch_head(batch_page->batch); 163d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso iov[i].iov_len = mnl_nlmsg_batch_size(batch_page->batch); 164d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso i++; 165d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso#ifdef NL_DEBUG 166d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, 167d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_batch_head(batch_page->batch), 168d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_batch_size(batch_page->batch), 169d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso sizeof(struct nfgenmsg)); 170d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso#endif 171d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso list_del(&batch_page->head); 172d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso free(batch_page->batch); 173d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso free(batch_page); 174d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso batch_num_pages--; 175d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 176d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 177d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return sendmsg(mnl_socket_get_fd(nl), &msg, 0); 178d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 179d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 180d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int cb_err(const struct nlmsghdr *nlh, void *data) 181d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 182d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso /* We can provide better error reporting than iptables-restore */ 183d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso errno = EINVAL; 184d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return MNL_CB_ERROR; 185d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 186d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 187d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic mnl_cb_t cb_ctl_array[NLMSG_MIN_TYPE] = { 188d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso [NLMSG_ERROR] = cb_err, 189d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso}; 190d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 191d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int mnl_nft_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); 203d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret == -1) { 204d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso perror("mnl_socket_sendmsg"); 205d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 206d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 207d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 208d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_ZERO(&readfds); 209d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_SET(fd, &readfds); 210d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 211d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso /* receive and digest all the acknowledgments from the kernel. */ 212d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = select(fd+1, &readfds, NULL, NULL, &tv); 213d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret == -1) { 214d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso perror("select"); 215d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 216d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 217d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso while (ret > 0 && FD_ISSET(fd, &readfds)) { 218d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = mnl_socket_recvfrom(h->nl, rcv_buf, sizeof(rcv_buf)); 219d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret == -1) { 220d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso perror("mnl_socket_recvfrom"); 221d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 222d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 223d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 224d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = mnl_cb_run2(rcv_buf, ret, 0, h->portid, 225d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NULL, NULL, cb_ctl_array, 226d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso MNL_ARRAY_SIZE(cb_ctl_array)); 227d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso /* Continue on error, make sure we get all acknoledgments */ 228d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret == -1) 229d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso err = errno; 230d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 231d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = select(fd+1, &readfds, NULL, NULL, &tv); 232d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret == -1) { 233d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso perror("select"); 234d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 235d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 236d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_ZERO(&readfds); 237d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso FD_SET(fd, &readfds); 238d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 239d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return err ? -1 : 0; 240d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 241d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 242d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic void mnl_nft_batch_put(struct mnl_nlmsg_batch *batch, int type, 243d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso uint32_t seq) 244d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 245d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct nlmsghdr *nlh; 246d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct nfgenmsg *nfg; 247d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 248d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nlh = mnl_nlmsg_put_header(mnl_nlmsg_batch_current(batch)); 249d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nlh->nlmsg_type = type; 250d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nlh->nlmsg_flags = NLM_F_REQUEST; 251d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nlh->nlmsg_seq = seq; 252d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 253d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); 254d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nfg->nfgen_family = AF_INET; 255d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nfg->version = NFNETLINK_V0; 256d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nfg->res_id = NFNL_SUBSYS_NFTABLES; 257d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 258d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (!mnl_nlmsg_batch_next(batch)) 259d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nft_batch_page_add(batch); 260d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 261d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 262d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic void mnl_nft_batch_begin(struct mnl_nlmsg_batch *batch, uint32_t seq) 263d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 264d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nft_batch_put(batch, NFNL_MSG_BATCH_BEGIN, seq); 265d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 266d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 267d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic void mnl_nft_batch_end(struct mnl_nlmsg_batch *batch, uint32_t seq) 268d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 269d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nft_batch_put(batch, NFNL_MSG_BATCH_END, seq); 270d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 271d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 272afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longostruct builtin_table xtables_ipv4[TABLES_MAX] = { 273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [RAW] = { 274384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "raw", 275e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 276e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 277e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 278890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 2795b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -300, /* NF_IP_PRI_RAW */ 280e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 281e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 282e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 283e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 284890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 2855b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -300, /* NF_IP_PRI_RAW */ 286e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 287e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 288e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 289384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [MANGLE] = { 291384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "mangle", 292e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 293e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 294e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "PREROUTING", 295890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 2965b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 297e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 298e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 299e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 300e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 301890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3025b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 303e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 304e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 305e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 306e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 307890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3085b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 309e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 310e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 311e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 312e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 313890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "route", 3145b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 315e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 316e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 317e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 318e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "POSTROUTING", 319890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3205b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = -150, /* NF_IP_PRI_MANGLE */ 321e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_POST_ROUTING, 322e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 323e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 325384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [FILTER] = { 326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "filter", 327e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 328e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 329e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 330890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3315b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 332e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 333e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 334e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 335e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 336890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3375b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 338e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 339e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 340e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 341e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 342890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3435b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 0, /* NF_IP_PRI_FILTER */ 344e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 345e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 346e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 347384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [SECURITY] = { 349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .name = "security", 350e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .chains = { 351e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 352e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "INPUT", 353890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3545b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 355e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 356e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 357e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 358e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "FORWARD", 359890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3605b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 361e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_FORWARD, 362e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 363e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso { 364e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .name = "OUTPUT", 365890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "filter", 3665b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso .prio = 150, /* NF_IP_PRI_SECURITY */ 367e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 368e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso }, 369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }, 371890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso [NAT] = { 372890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "nat", 373890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .chains = { 374890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 37586eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .name = "PREROUTING", 376890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 377890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = -100, /* NF_IP_PRI_NAT_DST */ 37886eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .hook = NF_INET_PRE_ROUTING, 379890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 380890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 381890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "INPUT", 382890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 383890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = 100, /* NF_IP_PRI_NAT_SRC */ 384890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_LOCAL_IN, 385890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 386890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso { 387890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .name = "POSTROUTING", 388890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .type = "nat", 389890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .prio = 100, /* NF_IP_PRI_NAT_SRC */ 390890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso .hook = NF_INET_POST_ROUTING, 391890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 39286eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso { 39386eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .name = "OUTPUT", 39486eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .type = "nat", 39586eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .prio = -100, /* NF_IP_PRI_NAT_DST */ 39686eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso .hook = NF_INET_LOCAL_OUT, 39786eed10c9f2c42e0f50eb4e527a48ee9e63146f4Pablo Neira Ayuso }, 398890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 399890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso }, 400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 40284909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo#include <linux/netfilter_arp.h> 40384909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo 40484909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longostruct builtin_table xtables_arp[TABLES_MAX] = { 40584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo [FILTER] = { 40684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "filter", 40784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .chains = { 40884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo { 40984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "INPUT", 41084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .type = "filter", 41184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .prio = NF_IP_PRI_FILTER, 41284909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .hook = NF_ARP_IN, 41384909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 41484909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo { 41584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "FORWARD", 41684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .type = "filter", 41784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .prio = NF_IP_PRI_FILTER, 41884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .hook = NF_ARP_FORWARD, 41984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 42084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo { 42184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .name = "OUTPUT", 42284909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .type = "filter", 42384909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .prio = NF_IP_PRI_FILTER, 42484909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo .hook = NF_ARP_OUT, 42584909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 42684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 42784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo }, 42884909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo}; 42984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longo 43084909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint 4315705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusonft_table_builtin_add(struct nft_handle *h, struct builtin_table *_t, 4325705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso bool dormant) 4335b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso{ 4345b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 4355b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso struct nlmsghdr *nlh; 4365b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso struct nft_table *t; 4375b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso int ret; 4385b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 439e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka if (_t->initialized) 440e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka return 0; 441e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka 4425b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso t = nft_table_alloc(); 4435b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso if (t == NULL) 4445b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso return -1; 4455b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 4465b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)_t->name); 4475705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (dormant) { 4485705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, 4495705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso NFT_TABLE_F_DORMANT); 4505705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso } 4515b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 4520391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family, 4535b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 4545b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 4555b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_table_free(t); 4565b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 457837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka#ifdef NLDEBUG 458837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka char tmp[1024]; 459837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka 460837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka nft_table_snprintf(tmp, sizeof(tmp), t, 0, 0); 461837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka printf("DEBUG: table: %s", tmp); 462837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 463837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka#endif 464837629fed24af7298fbf4cd28c7a51f24b70ee93Tomasz Bursztyka 4655b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 4665b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso if (ret < 0) { 4675b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso if (errno != EEXIST) 4685b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso perror("mnl-talk:nft_table_init_one"); 4695b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso } 470e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka 471e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka if (ret == 0 || errno == EEXIST) 472e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka _t->initialized = true; 473e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka 4745b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso return ret; 4755b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso} 4765b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso 47784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longostruct nft_chain * 478c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_alloc(struct builtin_table *table, 479c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *chain, int policy) 480384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 481384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 482384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 483384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 484384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) 485c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return NULL; 486384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 487384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table->name); 488384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain->name); 489384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_HOOKNUM, chain->hook); 4905b414b85c33912aec912d260502c8b0c0df794a1Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_PRIO, chain->prio); 491384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy); 492890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TYPE, (char *)chain->type); 493384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 494c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return c; 495c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 496c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 49784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longovoid 498c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_add(struct nft_handle *h, struct builtin_table *table, 499c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *chain, int policy) 500c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 501c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 502c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct nlmsghdr *nlh; 503c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct nft_chain *c; 504c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 505c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_builtin_alloc(table, chain, policy); 506c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 507c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return; 508c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 509890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso /* NLM_F_CREATE requests module autoloading */ 5100391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 511890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE, 512890fd9ef76ad0c11695fb0d09a88169e6e46584fPablo Neira Ayuso h->seq); 513384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 515384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_talk(h, nlh, NULL, NULL) < 0) { 517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 518c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso perror("mnl_talk:nft_chain_builtin_add"); 519c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 520c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 521c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 522c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in table already exists */ 52384909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longostruct builtin_table * 52484909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longonft_table_builtin_find(struct nft_handle *h, const char *table) 525c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 526c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int i; 527c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 528c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 529c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso for (i=0; i<TABLES_MAX; i++) { 53067da6075a4e7ced0e8cc452d73ce8ab06cbf8cd9Tomasz Bursztyka if (h->tables[i].name == NULL) 53167da6075a4e7ced0e8cc452d73ce8ab06cbf8cd9Tomasz Bursztyka break; 53267da6075a4e7ced0e8cc452d73ce8ab06cbf8cd9Tomasz Bursztyka 533afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo if (strcmp(h->tables[i].name, table) != 0) 534c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso continue; 535c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 536c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso found = true; 537c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso break; 538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 539c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 540afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo return found ? &h->tables[i] : NULL; 541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 543c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso/* find if built-in chain already exists */ 54484909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longostruct builtin_chain * 545e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusonft_chain_builtin_find(struct builtin_table *t, const char *chain) 546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 547e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int i; 548c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso bool found = false; 549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 550e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && t->chains[i].name != NULL; i++) { 551e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (strcmp(t->chains[i].name, chain) != 0) 552e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso continue; 553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 554e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso found = true; 555e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso break; 556e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso } 557e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso return found ? &t->chains[i] : NULL; 558e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso} 559e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 560e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayusostatic void 561e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso__nft_chain_builtin_init(struct nft_handle *h, 562e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso struct builtin_table *table, const char *chain, 563e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int policy) 564e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso{ 565e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int i, default_policy; 566e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 567e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* Initialize all built-in chains. Exception, for e one received as 568e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso * parameter, set the default policy as requested. 569e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso */ 570e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso for (i=0; i<NF_IP_NUMHOOKS && table->chains[i].name != NULL; i++) { 571e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (chain && strcmp(table->chains[i].name, chain) == 0) 572e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy = policy; 573e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso else 574e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy = NF_ACCEPT; 575e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 576e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso nft_chain_builtin_add(h, table, &table->chains[i], 577e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso default_policy); 578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 579c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso} 580c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 58184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint 582c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusonft_chain_builtin_init(struct nft_handle *h, const char *table, 583c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso const char *chain, int policy) 584c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso{ 585c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso int ret = 0; 586c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *t; 587c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 588afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo t = nft_table_builtin_find(h, table); 589c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (t == NULL) { 590c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso ret = -1; 591c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso goto out; 592c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 5935705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (nft_table_builtin_add(h, t, false) < 0) { 594e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* Built-in table already initialized, skip. */ 595e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso if (errno == EEXIST) 596e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso goto out; 597c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 598e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso __nft_chain_builtin_init(h, t, chain, policy); 599c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayusoout: 600c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return ret; 601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 602384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 6037244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztykastatic bool nft_chain_builtin(struct nft_chain *c) 6047244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka{ 6057244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka /* Check if this chain has hook number, in that case is built-in. 6067244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka * Should we better export the flags to user-space via nf_tables? 6077244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka */ 6087244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka return nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM) != NULL; 6097244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka} 6107244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka 611afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longoint nft_init(struct nft_handle *h, struct builtin_table *t) 612384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 613384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->nl = mnl_socket_open(NETLINK_NETFILTER); 614384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (h->nl == NULL) { 615384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_open"); 616384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 617384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 618384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 619384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0) { 620384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_bind"); 621384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return -1; 622384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 623384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso h->portid = mnl_socket_get_portid(h->nl); 624afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo h->tables = t; 625384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 626d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso INIT_LIST_HEAD(&h->rule_list); 627d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 628d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso h->batch = mnl_nft_batch_alloc(); 629d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 630384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 631384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 632384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 633384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusovoid nft_fini(struct nft_handle *h) 634384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 635384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(h->nl); 636b0194cea194b510c675ca05415da15cff57afe47Ana Rey free(mnl_nlmsg_batch_head(h->batch)); 637b0194cea194b510c675ca05415da15cff57afe47Ana Rey mnl_nlmsg_batch_stop(h->batch); 638384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 639384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 640384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_table_add(struct nft_handle *h, const struct nft_table *t) 641384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 642384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 643384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 644384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 6450391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family, 646384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 647384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 648384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 649384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 650384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 651384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 652384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_add(struct nft_handle *h, const struct nft_chain *c) 653384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 654384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 655384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 656384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 6570391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 658384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 659384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 660384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 661384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 662384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 663384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 6645705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusoint nft_table_set_dormant(struct nft_handle *h, const char *table) 6655705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso{ 6665705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso int ret = 0, i; 6675705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso struct builtin_table *t; 6685705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 669afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo t = nft_table_builtin_find(h, table); 6705705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (t == NULL) { 6715705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso ret = -1; 6725705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso goto out; 6735705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso } 6745705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso /* Add this table as dormant */ 6755705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (nft_table_builtin_add(h, t, true) < 0) { 6765705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso /* Built-in table already initialized, skip. */ 6775705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (errno == EEXIST) 6785705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso goto out; 6795705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso } 6805705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso for (i=0; t->chains[i].name != NULL && i<NF_INET_NUMHOOKS; i++) 6815705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso __nft_chain_builtin_init(h, t, t->chains[i].name, NF_ACCEPT); 6825705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusoout: 6835705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso return ret; 6845705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso} 6855705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 6865705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayusoint nft_table_wake_dormant(struct nft_handle *h, const char *table) 6875705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso{ 6885705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 6895705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso struct nlmsghdr *nlh; 6905705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso struct nft_table *t; 6915705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 6925705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso t = nft_table_alloc(); 6935705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso if (t == NULL) 6945705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso return -1; 6955705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 6965705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)table); 6975705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, 0); 6985705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 6990391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family, 7005705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso NLM_F_ACK, h->seq); 7015705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_nlmsg_build_payload(nlh, t); 7025705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_free(t); 7035705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 7045705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso return mnl_talk(h, nlh, NULL, NULL); 7055705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso} 7065705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso 707384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_chain_print_debug(struct nft_chain *c, struct nlmsghdr *nlh) 708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0); 713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("DEBUG: chain: %s", tmp); 714384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 716384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 717384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 719384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_chain_set(struct nft_handle *h, const char *table, 720384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain, int policy, 721384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters) 722384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 723384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 724384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 725384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 726c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_table *_t; 727c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso struct builtin_chain *_c; 728e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso int ret; 729c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 730afae1f841bc2c4b39a38fa97d271f3877d00bf3aGiuseppe Longo _t = nft_table_builtin_find(h, table); 731c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* if this built-in table does not exists, create it */ 732c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_t != NULL) 7335705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57Pablo Neira Ayuso nft_table_builtin_add(h, _t, false); 734c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso 735e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso _c = nft_chain_builtin_find(_t, chain); 736c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (_c != NULL) { 737c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso /* This is a built-in chain */ 738c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso c = nft_chain_builtin_alloc(_t, _c, policy); 739c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso if (c == NULL) 740c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso return -1; 741c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } else { 74220c156f9f4c43857a622f015a3022517601c3600Tomasz Bursztyka errno = ENOENT; 74320c156f9f4c43857a622f015a3022517601c3600Tomasz Bursztyka return -1; 744c74f398c58e7b77ca1c82a15d0b2e9eed4fb82adPablo Neira Ayuso } 745384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 746384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 747384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, 748384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->bcnt); 749384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, 750384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso counters->pcnt); 751384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 752384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 7530391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 754690ea18fdd6f8bc12322a729a2f7c97d8e731c43Tomasz Bursztyka h->restore ? NLM_F_ACK|NLM_F_CREATE : 755384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 756384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 757384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 758384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_print_debug(c, nlh); 759384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 760384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 761384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 762384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 763384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 764384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_chain_policy"); 765384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 766384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 767384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 768384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 769384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_set(struct nft_handle *h, const char *table, 770384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain, const char *policy, 771384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters) 772384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 773384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = -1; 774384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 775384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_chain_set; 776384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 777384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(policy, "DROP") == 0) 778384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_set(h, table, chain, NF_DROP, counters); 779384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else if (strcmp(policy, "ACCEPT") == 0) 780384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_set(h, table, chain, NF_ACCEPT, counters); 781384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 782384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 783384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 784384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 785384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 786f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int __add_match(struct nft_rule_expr *e, struct xt_entry_match *m) 787384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 788384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *info; 789384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 790384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_MT_NAME, m->u.user.name, strlen(m->u.user.name)); 791384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(e, NFT_EXPR_MT_REV, m->u.user.revision); 792384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 793384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso info = calloc(1, m->u.match_size); 794384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (info == NULL) 795f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 796384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 7975eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso memcpy(info, m->data, m->u.match_size - sizeof(*m)); 798384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_MT_INFO, info, m->u.match_size - sizeof(*m)); 799f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 800f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 801384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 802384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 803c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayusoint add_match(struct nft_rule *r, struct xt_entry_match *m) 804384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 805384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 806f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka int ret; 807384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 808384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("match"); 809384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 810f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 811384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 812f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = __add_match(expr, m); 813384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 814f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 815f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return ret; 816384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 817384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 818f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztykastatic int __add_target(struct nft_rule_expr *e, struct xt_entry_target *t) 819384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 8205eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso void *info; 821384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 822384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_TG_NAME, t->u.user.name, 823384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strlen(t->u.user.name)); 824384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(e, NFT_EXPR_TG_REV, t->u.user.revision); 825384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 8265eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso info = calloc(1, t->u.target_size); 8275eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso if (info == NULL) 8285eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso return -ENOMEM; 829384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 8305eed9118f2620ac07edd553599e2415f00d6f8f3Pablo Neira Ayuso memcpy(info, t->data, t->u.target_size - sizeof(*t)); 831384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set(e, NFT_EXPR_TG_INFO, info, t->u.target_size - sizeof(*t)); 832f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 833f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 834384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 835384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 83684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint add_target(struct nft_rule *r, struct xt_entry_target *t) 837384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 839f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka int ret; 840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 841384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("target"); 842384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 843f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 844384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 845f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka ret = __add_target(expr, t); 846384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 847f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 848f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return ret; 849384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 850384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 85184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint add_jumpto(struct nft_rule *r, const char *name, int verdict) 852384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 853384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 854384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 855384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("immediate"); 856384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 857f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 858384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 859384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT); 860384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict); 861384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_str(expr, NFT_EXPR_IMM_CHAIN, (char *)name); 862384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 863f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 864f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 865384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 866384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 86784909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint add_verdict(struct nft_rule *r, int verdict) 868384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 869384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 870384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 871384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("immediate"); 872384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 873f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT); 876384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict); 877384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 878f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 879f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 880384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 881384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 882c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayusoint add_action(struct nft_rule *r, struct iptables_command_state *cs, 883d007e1a59e4beaddab430992302d43b122ffc801Pablo Neira Ayuso bool goto_set) 884c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso{ 885c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso int ret = 0; 886c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso 887c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso /* If no target at all, add nothing (default to continue) */ 888c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso if (cs->target != NULL) { 889c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso /* Standard target? */ 890c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0) 891c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_verdict(r, NF_ACCEPT); 892c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0) 893c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_verdict(r, NF_DROP); 894c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0) 895c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_verdict(r, NFT_RETURN); 896c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else 897c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_target(r, cs->target->t); 898c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso } else if (strlen(cs->jumpto) > 0) { 899c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso /* Not standard, then it's a go / jump to chain */ 900d007e1a59e4beaddab430992302d43b122ffc801Pablo Neira Ayuso if (goto_set) 901c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_jumpto(r, cs->jumpto, NFT_GOTO); 902c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso else 903c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso ret = add_jumpto(r, cs->jumpto, NFT_JUMP); 904c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso } 905c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso return ret; 906c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso} 907c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso 908384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_rule_print_debug(struct nft_rule *r, struct nlmsghdr *nlh) 909384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 910384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#ifdef NLDEBUG 911384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char tmp[1024]; 912384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 913384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0); 914384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("DEBUG: rule: %s", tmp); 915384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg)); 916384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso#endif 917384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 918384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 91984909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longoint add_counters(struct nft_rule *r, uint64_t packets, uint64_t bytes) 920384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 921384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_expr *expr; 922384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 923384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso expr = nft_rule_expr_alloc("counter"); 924384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (expr == NULL) 925f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return -ENOMEM; 926384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 927384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_BYTES, packets); 928384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_PACKETS, bytes); 929384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 930384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_add_expr(r, expr); 931f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka 932f6b30db46e5e3d32c76b186361853b5a5ecaf99fTomasz Bursztyka return 0; 933384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 934384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 9354ef77b6d1b52e1fe52a7fd48d38d9233f0961640Pablo Neira Ayusovoid add_compat(struct nft_rule *r, uint32_t proto, bool inv) 9362a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso{ 9372a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_PROTO, proto); 9382a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_FLAGS, 9392a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso inv ? NFT_RULE_COMPAT_F_INV : 0); 9402a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso} 9412a87a024e1f77407e332086a4fa664e048280195Pablo Neira Ayuso 942cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusostatic struct nft_rule * 943cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusonft_rule_new(struct nft_handle *h, const char *chain, const char *table, 944c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso void *data) 945384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 946384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 947384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 948384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 949cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso if (r == NULL) 950cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return NULL; 951384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 952d370c4ad803c37eedfbee5963fac6f7e9968939cTomasz Bursztyka nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, h->family); 953384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table); 954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain); 955384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 956c6836c19592dbe1a8be9b0ad76c0ae09abcb82e7Pablo Neira Ayuso if (h->ops->add(r, data) < 0) 957cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso goto err; 958cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 959cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return r; 960cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoerr: 961cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_rule_free(r); 962cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return NULL; 963cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso} 964cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 965d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusoenum rule_update_type { 966d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NFT_DO_APPEND, 967d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NFT_DO_INSERT, 968d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NFT_DO_REPLACE, 969d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NFT_DO_DELETE, 970d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NFT_DO_FLUSH, 971d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NFT_DO_COMMIT, 972d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso NFT_DO_ABORT, 973d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso}; 974d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 975d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostruct rule_update { 976d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct list_head head; 977d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso enum rule_update_type type; 978d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct nft_rule *rule; 979d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso}; 980d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 981d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int rule_update_add(struct nft_handle *h, enum rule_update_type type, 982d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct nft_rule *r) 983d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso{ 984d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct rule_update *rupd; 985d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 986d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso rupd = calloc(1, sizeof(struct rule_update)); 987d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (rupd == NULL) 988d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 989d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 990d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso rupd->rule = r; 991d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso rupd->type = type; 992d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso list_add_tail(&rupd->head, &h->rule_list); 993d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso h->rule_list_num++; 994d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 995d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 996d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso} 997d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 998cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoint 999cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusonft_rule_append(struct nft_handle *h, const char *chain, const char *table, 1000b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso void *data, uint64_t handle, bool verbose) 1001cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso{ 1002cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso struct nft_rule *r; 1003d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso int type; 1004cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1005cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 1006cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 1007cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_chain_builtin_init(h, table, chain, NF_ACCEPT); 1008cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1009cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_fn = nft_rule_append; 1010cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1011b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_new(h, chain, table, data); 1012d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (r == NULL) 1013d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 1014384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 10150a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka if (handle > 0) { 10160a366d8696582e979d55f6832a797d1217f4b908Tomasz Bursztyka nft_rule_attr_set(r, NFT_RULE_ATTR_HANDLE, &handle); 1017d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso type = NFT_DO_REPLACE; 1018cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso } else 1019d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso type = NFT_DO_APPEND; 1020384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1021d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (rule_update_add(h, type, r) < 0) 1022d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_free(r); 1023384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1024d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 1; 1025384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1026384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 10271ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayusovoid 10288877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longonft_rule_print_save(const void *data, 1029cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka struct nft_rule *r, enum nft_rule_print type, 1030cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka unsigned int format) 1031384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 10321ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso const char *chain = nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 1033cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka int family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY); 1034cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka struct nft_family_ops *ops; 1035384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1036384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 10371ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso switch(type) { 10381ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso case NFT_RULE_APPEND: 10391ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso printf("-A %s ", chain); 10401ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso break; 10411ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso case NFT_RULE_DEL: 10421ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso printf("-D %s ", chain); 10431ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso break; 10441ff21a68502d67e056100da7e0da074467bc08edPablo Neira Ayuso } 1045384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1046cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka ops = nft_family_ops_lookup(family); 1047cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 10488877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo if (ops->save_firewall) 10498877968858a8dd6b7ae096988d57a7511c81733dGiuseppe Longo ops->save_firewall(data, format); 1050cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 1051384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1052384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1053384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_chain_list_cb(const struct nlmsghdr *nlh, void *data) 1054384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1055384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1056384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list = data; 1057384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1058384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 1059384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (c == NULL) { 1060384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1061384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1062384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1063384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1064384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_nlmsg_parse(nlh, c) < 0) { 1065384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1066384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1067384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1068384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1069f77e1aca9aa8851b469f79c2db80ddb6f49253b2Pablo Neira Ayuso nft_chain_list_add_tail(c, list); 1070384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1071384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1072384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1073384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 1074384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1075384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1076384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1077384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1078384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_chain_list *nft_chain_list_get(struct nft_handle *h) 1079384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1080384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1081384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1082384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1083384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1084384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1085384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_alloc(); 1086384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1087b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso errno = ENOMEM; 1088b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return NULL; 1089384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1090384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 10910391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, 1092384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1093384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1094384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_chain_list_cb, list); 1095384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1096384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_chain_list_get"); 1097384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1098384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1099384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1101384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostruct nft_chain_list *nft_chain_dump(struct nft_handle *h) 1102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1103384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return nft_chain_list_get(h); 1104384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1105384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1106384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic const char *policy_name[NF_ACCEPT+1] = { 1107384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_DROP] = "DROP", 1108384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso [NF_ACCEPT] = "ACCEPT", 1109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso}; 1110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1111384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void nft_chain_print_save(struct nft_chain *c, bool basechain) 1112384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain = nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1114384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint64_t pkts = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS); 1115384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint64_t bytes = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES); 1116384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1117384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* print chain name */ 1118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (basechain) { 1119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t pol = NF_ACCEPT; 1120384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1121384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* no default chain policy? don't crash, display accept */ 1122384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_POLICY)) 1123384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso pol = nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 1124384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11250a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(":%s %s [%"PRIu64":%"PRIu64"]\n", chain, policy_name[pol], 1126384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso pkts, bytes); 1127384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 11280a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(":%s - [%"PRIu64":%"PRIu64"]\n", chain, pkts, bytes); 1129384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1130384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1131384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_save(struct nft_handle *h, struct nft_chain_list *list, 1132384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table) 1133384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1134384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1135384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1136384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1137384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1138b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1139384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1140384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1141384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1143384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 1144384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1145384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 1146384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1147384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 1148384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1149384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11507244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka basechain = nft_chain_builtin(c); 1151384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_print_save(c, basechain); 1152384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1153384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1154384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1155384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1156d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_chain_list_iter_destroy(iter); 1157384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1158384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1159384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1160384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1161384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1162384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_rule_list_cb(const struct nlmsghdr *nlh, void *data) 1163384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1164384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1165384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list = data; 1166384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1167384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 1168384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) { 1169384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1170384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1171384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1172384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1173384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_rule_nlmsg_parse(nlh, r) < 0) { 1174384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1177384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1178f77e1aca9aa8851b469f79c2db80ddb6f49253b2Pablo Neira Ayuso nft_rule_list_add_tail(r, list); 1179384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1180384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1181384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1182384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_free(r); 1183137cc981906f356c971da6de13e777a419382ff4Giuseppe Longo nft_rule_list_free(list); 1184384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1185384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1186384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1187384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1188384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_rule_list *nft_rule_list_get(struct nft_handle *h) 1189384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1190384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1191384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1192384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 1193384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1194384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1195384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_alloc(); 1196b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1197384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1198384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 11990391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family, 1200384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1201384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1202384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_rule_list_cb, list); 1203384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1204384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_rule_save"); 1205384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 1206384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return NULL; 1207384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1208384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1209384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1210384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1211384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1212384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_save(struct nft_handle *h, const char *table, bool counters) 1213384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1214384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 1215384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list_iter *iter; 1216384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1217384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1218384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 1219b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1220384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1221384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1222384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 1223b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1224384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1225384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1226384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1227384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 1228384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 1229384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 1230cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka struct iptables_command_state cs = {}; 1231384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1232384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0) 1233384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1234384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1235cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_to_iptables_command_state(r, &cs); 1236cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 1237cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_print_save(&cs, r, NFT_RULE_APPEND, 1238cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka counters ? 0 : FMT_NOCOUNTS); 1239384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1240384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1241384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1242384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1243384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1244d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_rule_list_iter_destroy(iter); 1245384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 1246384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1247384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1248384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 1249384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1250384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1251384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1252384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain) 1253384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1254384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1255384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1256384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_alloc(); 1257384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (r == NULL) 1258384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return; 1259384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1260384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table); 1261384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain); 1262384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1263d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (rule_update_add(h, NFT_DO_FLUSH, r) < 0) 1264d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_free(r); 1265384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1266384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1267384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) 1268384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1269384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1270384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1271384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1272384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1273384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1274384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_flush; 1275384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1276384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_get(h); 1277384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1278384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1279384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1280384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1281384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1282384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1283b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1284b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 1285384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1286384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1287384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1288384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1289384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1291384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1292384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1293384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1294384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1295384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1296384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1297384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1298384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1299384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso __nft_rule_flush(h, table_name, chain_name); 1300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 130136ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 130236ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 1303384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1304384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1305384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1306384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1307d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_chain_list_iter_destroy(iter); 1308384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1309384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1310384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1311384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1312384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1313384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1314384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1315384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table) 1316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1317384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1318384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1320384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1321384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1322e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 13238b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 13248b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); 1325e17b5f15c2beda86565a8f4e55fdf12ceb20dd59Pablo Neira Ayuso 1326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_alloc(); 1327b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (c == NULL) 1328b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return 0; 1329384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table); 1331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain); 1332384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 13330391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 1334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK|NLM_F_EXCL, h->seq); 1335384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 1336384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_free(c); 1337384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1338384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 1339384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1340384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST) 1341384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_chain_add"); 1342384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1343384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1344384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1347384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int __nft_chain_del(struct nft_handle *h, struct nft_chain *c) 1349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1350384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1352384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 13540391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_DELCHAIN, h->family, 1355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_ACK, h->seq); 1356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_nlmsg_build_payload(nlh, c); 1357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, NULL, NULL); 1359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) { 1360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (errno != EEXIST && errno != ENOENT) 1361384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:__nft_chain_del"); 1362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1364384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1365384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1366384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table) 1368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 1370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 1371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 1372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 1373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int deleted_ctr = 0; 1374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1375384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_list_get(h); 1376384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1377384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1380b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1381b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 1382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1384384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 1385384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table_name = 1386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 1387384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 1388384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 1389384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1390384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* don't delete built-in chain */ 1391384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_builtin(c)) 1392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1394384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 1395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1396384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain != NULL && strcmp(chain, chain_name) != 0) 1398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1399384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1400384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = __nft_chain_del(h, c); 1401384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1402384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso break; 1403384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1404384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso deleted_ctr++; 140536ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo 140636ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 140736ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 1408384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1409384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 1410384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1411384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1412d01b2c28c8101f0d24e1db3f146fd845c2a634e8Giuseppe Longo nft_chain_list_iter_destroy(iter); 1413384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1414384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 1415384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1416384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* chain not found */ 1417384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0 && deleted_ctr == 0) 1418384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 1419384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1420384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1421384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1422384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1423384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14240aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusostruct nft_chain * 1425e127d223d01aaa0886c7f279110ac36651b9a057Tomasz Bursztykanft_chain_list_find(struct nft_chain_list *list, 14260aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso const char *table, const char *chain) 14279c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso{ 14289c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 14299c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso struct nft_chain *c; 14309c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14319c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 1432b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 14339c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return NULL; 14349c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14359c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 14369c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso while (c != NULL) { 14379c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso const char *table_name = 14389c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 14399c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso const char *chain_name = 14409c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 14419c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14429c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (strcmp(table, table_name) != 0) 14439c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso goto next; 14449c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14459c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (strcmp(chain, chain_name) != 0) 14469c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso goto next; 14479c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14480aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_list_iter_destroy(iter); 14499c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return c; 14509c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayusonext: 14519c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 14529c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso } 14530aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_list_iter_destroy(iter); 14549c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return NULL; 14559c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso} 14569c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14570aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusostatic struct nft_chain * 14580aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusonft_chain_find(struct nft_handle *h, const char *table, const char *chain) 14590aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso{ 14600aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain_list *list; 14610aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 14620aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso list = nft_chain_list_get(h); 1463b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 14640aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return NULL; 14650aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1466e127d223d01aaa0886c7f279110ac36651b9a057Tomasz Bursztyka return nft_chain_list_find(list, table, chain); 14670aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso} 14680aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1469384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_chain_user_rename(struct nft_handle *h,const char *chain, 1470384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, const char *newname) 1471384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 14724493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka char buf[MNL_SOCKET_BUFFER_SIZE]; 14734493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka struct nlmsghdr *nlh; 14744493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka struct nft_chain *c; 14759c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso uint64_t handle; 1476384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1477384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14784493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka /* If built-in chains don't exist for this table, create them */ 14798b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 14808b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); 14814493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 14829c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso /* Find the old chain to be renamed */ 14839c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso c = nft_chain_find(h, table, chain); 14849c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso if (c == NULL) { 14859c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso errno = ENOENT; 14869c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso return -1; 14879c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso } 14889c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso handle = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_HANDLE); 14899c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso 14909c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso /* Now prepare the new name for the chain */ 14914493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka c = nft_chain_alloc(); 1492b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (c == NULL) 14934493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka return -1; 14944493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 14954493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table); 14969c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)newname); 14979c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_HANDLE, handle); 1498384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 14990391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family, 15009c541721d318598db45986ee2fd61491fadb53d0Pablo Neira Ayuso NLM_F_ACK, h->seq); 15014493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka nft_chain_nlmsg_build_payload(nlh, c); 15024493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka nft_chain_free(c); 15034493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 15044493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka ret = mnl_talk(h, nlh, NULL, NULL); 15054493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka if (ret < 0) { 15064493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka if (errno != EEXIST) 15074493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka perror("mnl_talk:nft_chain_rename"); 15084493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka } 15094493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka 15104493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka /* the core expects 1 for success and 0 for error */ 15114493582ccb60a443fc7efeca78edafbefc689aa3Tomasz Bursztyka return ret == 0 ? 1 : 0; 1512384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1513384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1514384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int nft_table_list_cb(const struct nlmsghdr *nlh, void *data) 1515384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1516384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1517384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list = data; 1518384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1519384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_alloc(); 1520384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (t == NULL) { 1521384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("OOM"); 1522384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1523384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1524384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1525384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_table_nlmsg_parse(nlh, t) < 0) { 1526384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("nft_rule_nlmsg_parse"); 1527384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto out; 1528384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1529384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1530f77e1aca9aa8851b469f79c2db80ddb6f49253b2Pablo Neira Ayuso nft_table_list_add_tail(t, list); 1531384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1532384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1533384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoout: 1534384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_free(t); 1535384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1536384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return MNL_CB_OK; 1537384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1538384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1539384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic struct nft_table_list *nft_table_list_get(struct nft_handle *h) 1540384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1541384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 1542384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 1543384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1544384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1545384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1546384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_alloc(); 1547b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1548384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1549384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 15500391677c1a0b28c14d01febd9628a543e8e5fd62Tomasz Bursztyka nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family, 1551384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso NLM_F_DUMP, h->seq); 1552384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1553384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_talk(h, nlh, nft_table_list_cb, list); 1554384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret < 0) 1555384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_talk:nft_table_list_get"); 1556384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1557384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return list; 1558384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1559384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1560384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusobool nft_table_find(struct nft_handle *h, const char *tablename) 1561384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1562384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1563384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list_iter *iter; 1564384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1565384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool ret = false; 1566384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1567384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_get(h); 1568384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) 1569384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1570384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1571384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_table_list_iter_create(list); 1572b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1573384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1574384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1575384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1576384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1577384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *this_tablename = 1578384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_attr_get(t, NFT_TABLE_ATTR_NAME); 1579384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1580384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(tablename, this_tablename) == 0) 1581384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return true; 1582384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1583384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1584384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1585384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1586384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_free(list); 1587384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1588384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1589384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1590384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1591384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1592384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_for_each_table(struct nft_handle *h, 1593384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int (*func)(struct nft_handle *h, const char *tablename, bool counters), 1594384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool counters) 1595384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1596384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 1; 1597384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list *list; 1598384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table_list_iter *iter; 1599384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_table *t; 1600384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1601384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_table_list_get(h); 1602384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (list == NULL) { 1603384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = 0; 1604384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 1605384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1606384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1607384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_table_list_iter_create(list); 1608b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1609384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1610384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1611384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1612384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (t != NULL) { 1613384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *tablename = 1614384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_attr_get(t, NFT_TABLE_ATTR_NAME); 1615384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1616384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso func(h, tablename, counters); 1617384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1618384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso t = nft_table_list_iter_next(iter); 1619384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1620384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1621384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_table_list_free(list); 1622384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1623384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 1624384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* the core expects 1 for success and 0 for error */ 1625384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret == 0 ? 1 : 0; 1626384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1627384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 16280aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusoint nft_table_purge_chains(struct nft_handle *h, const char *this_table, 16290aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain_list *chain_list) 16300aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso{ 16310aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain_list_iter *iter; 16320aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso struct nft_chain *chain_obj; 16330aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16340aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso iter = nft_chain_list_iter_create(chain_list); 1635b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 16360aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return 0; 16370aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16380aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso chain_obj = nft_chain_list_iter_next(iter); 16390aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso while (chain_obj != NULL) { 16400aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso const char *table = 16410aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_attr_get_str(chain_obj, NFT_CHAIN_ATTR_TABLE); 16420aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16430aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (strcmp(this_table, table) != 0) 16440aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso goto next; 16450aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16460aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (nft_chain_builtin(chain_obj)) 16470aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso goto next; 16480aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16490aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if ( __nft_chain_del(h, chain_obj) < 0) { 16500aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso if (errno != EBUSY) 16510aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return -1; 16520aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso } 16530aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayusonext: 16540aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso chain_obj = nft_chain_list_iter_next(iter); 16550aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso } 16560aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso nft_chain_list_iter_destroy(iter); 16570aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 16580aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso return 0; 16590aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso} 16600aad20f3979e3b6becd40e4ed5bba8d09d90706ePablo Neira Ayuso 1661d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int __nft_rule_del(struct nft_handle *h, struct nft_rule_list *list, 1662d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct nft_rule *r) 1663384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1664384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret; 1665384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1666d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_list_del(r); 1667384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1668d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = rule_update_add(h, NFT_DO_DELETE, r); 1669d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret < 0) { 1670d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_free(r); 1671d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return -1; 1672d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 1673d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 1; 1674384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1675384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 167684909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longostruct nft_rule_list *nft_rule_list_create(struct nft_handle *h) 1677384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1678b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso return nft_rule_list_get(h); 16793aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso} 16803aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 168184909d171585d77fe769f03e2b1b96eab0aa0213Giuseppe Longovoid nft_rule_list_destroy(struct nft_rule_list *list) 16823aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso{ 16833aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_free(list); 16843aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso} 16853aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 16863aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayusostatic struct nft_rule * 1687e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayusonft_rule_find(struct nft_handle *h, struct nft_rule_list *list, 1688e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso const char *chain, const char *table, void *data, int rulenum) 16893aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso{ 16903aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 16913aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list_iter *iter; 16923aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int rule_ctr = 0; 16933aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso bool found = false; 16943aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1695384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 1696b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1697384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1698384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1699384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1700384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 1701384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 1702384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 1703384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 1704384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 1705384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1706384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 1707384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) { 1708384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("different chain / table\n"); 1709384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1710384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1711384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1712384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (rulenum >= 0) { 1713384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Delete by rule number case */ 17144acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka if (rule_ctr != rulenum) 1715384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 17164acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka found = true; 17174acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka break; 1718384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 1719e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso found = h->ops->rule_find(h->ops, r, data); 1720e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso if (found) 1721e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso break; 1722384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1723384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 17244acee778f5712c4cc574e328183a3252ad81a802Tomasz Bursztyka rule_ctr++; 1725384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1726384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1727384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1728384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_iter_destroy(iter); 1729384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 17303aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return found ? r : NULL; 1731384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1732384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1733384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_check(struct nft_handle *h, const char *chain, 1734b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, bool verbose) 1735384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 17363aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 17373aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret; 17383aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1739384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_check; 1740384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 17413aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 1742b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 17433aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 17443aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1745b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso ret = nft_rule_find(h, list, chain, table, data, -1) ? 1 : 0; 17463aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (ret == 0) 17473aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 17483aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 17493aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 17503aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 17513aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 1752384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1753384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1754384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete(struct nft_handle *h, const char *chain, 1755b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, bool verbose) 1756384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 17573aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 17583aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 17593aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 17603aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1761384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete; 1762384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 17633aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 1764b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 17653aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 17663aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1767b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_find(h, list, chain, table, data, -1); 17683aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 1769d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret =__nft_rule_del(h, list, r); 1770d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret < 0) 1771d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso errno = ENOMEM; 17723aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 17733aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 17743aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 17753aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 17763aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 17773aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 1778384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1779384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1780cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusostatic int 1781cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusonft_rule_add(struct nft_handle *h, const char *chain, 1782cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso const char *table, struct iptables_command_state *cs, 1783cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso uint64_t handle, bool verbose) 1784cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso{ 1785cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso struct nft_rule *r; 1786cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1787cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso r = nft_rule_new(h, chain, table, cs); 1788d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (r == NULL) 1789d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 1790d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 179166a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (handle > 0) 179266a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso nft_rule_attr_set_u64(r, NFT_RULE_ATTR_POSITION, handle); 1793cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1794d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (rule_update_add(h, NFT_DO_INSERT, r) < 0) { 1795d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_free(r); 1796d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 1797cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso } 1798cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1799d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 1; 1800cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso} 1801cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1802cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoint nft_rule_insert(struct nft_handle *h, const char *chain, 1803b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, int rulenum, bool verbose) 1804cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso{ 1805cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso struct nft_rule_list *list; 1806cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso struct nft_rule *r; 180766a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso uint64_t handle = 0; 1808cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1809cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso /* If built-in chains don't exist for this table, create them */ 1810cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 1811cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_chain_builtin_init(h, table, chain, NF_ACCEPT); 1812cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1813cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_fn = nft_rule_insert; 1814cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 181566a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (rulenum > 0) { 181666a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso list = nft_rule_list_create(h); 181766a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (list == NULL) 181866a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso goto err; 1819cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1820b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_find(h, list, chain, table, data, rulenum); 182166a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso if (r == NULL) { 182266a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso errno = ENOENT; 182366a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso goto err; 182466a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso } 1825cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 182666a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso handle = nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE); 182766a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso DEBUGP("adding after rule handle %"PRIu64"\n", handle); 1828cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 182966a5399b6a4383ea4081d99ae852eebc1d65f265Pablo Neira Ayuso nft_rule_list_destroy(list); 1830cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso } 1831cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1832b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso return nft_rule_add(h, chain, table, data, handle, verbose); 1833cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayusoerr: 1834cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_rule_list_destroy(list); 1835cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso return 0; 1836cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso} 1837cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso 1838384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_delete_num(struct nft_handle *h, const char *chain, 18393aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso const char *table, int rulenum, bool verbose) 1840384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 18413aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 18423aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 18433aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 18443aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1845384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_delete_num; 1846384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 18473aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 1848b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 18493aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 18503aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1851e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso r = nft_rule_find(h, list, chain, table, NULL, rulenum); 18523aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 18533aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso ret = 1; 18543aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 18553aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso DEBUGP("deleting rule by number %d\n", rulenum); 1856d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = __nft_rule_del(h, list, r); 1857d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret < 0) 1858d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso errno = ENOMEM; 18593aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 18603aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 18613aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 18623aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 18633aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 18643aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 1865384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1866384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1867384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_replace(struct nft_handle *h, const char *chain, 1868b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso const char *table, void *data, int rulenum, bool verbose) 1869384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 18703aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso int ret = 0; 18713aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule *r; 18723aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso struct nft_rule_list *list; 1873384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1874384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_fn = nft_rule_replace; 1875384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 18763aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso list = nft_rule_list_create(h); 1877b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 18783aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return 0; 18793aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 1880b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso r = nft_rule_find(h, list, chain, table, data, rulenum); 18813aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso if (r != NULL) { 18821298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso DEBUGP("replacing rule with handle=%llu\n", 18831298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso (unsigned long long) 18841298a1014bc14c45de50cc242779dfa382c456c9Pablo Neira Ayuso nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE)); 1885384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1886b756cf08d6eff885d808504c674bd7eb5ebabfbbPablo Neira Ayuso ret = nft_rule_append(h, chain, table, data, 1887cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE), 1888cf95f347e52ca8badc6a7149045d9c09f4fa666dPablo Neira Ayuso verbose); 18893aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso } else 18903aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso errno = ENOENT; 18913aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 18923aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso nft_rule_list_destroy(list); 18933aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso 18943aea037f359795edeb69426e2dde63c59540ba5fPablo Neira Ayuso return ret; 1895384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1896384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1897384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 1898384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoprint_header(unsigned int format, const char *chain, const char *pol, 1899384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const struct xt_counters *counters, bool basechain, uint32_t refs) 1900384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1901384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("Chain %s", chain); 1902384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (basechain) { 1903384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" (policy %s", pol); 1904384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOCOUNTS)) { 1905384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputc(' ', stdout); 190636cba824e1689c6255d4e33b7fa82541a774609bPablo Neira Ayuso xtables_print_num(counters->pcnt, (format|FMT_NOTABLE)); 1907384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("packets, ", stdout); 190836cba824e1689c6255d4e33b7fa82541a774609bPablo Neira Ayuso xtables_print_num(counters->bcnt, (format|FMT_NOTABLE)); 1909384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("bytes", stdout); 1910384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1911384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(")\n"); 1912384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 1913384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(" (%u references)\n", refs); 1914384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1915384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1916384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_LINENUMBERS) 1917384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-4s ", "%s "), "num"); 1918384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOCOUNTS)) { 1919384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_KILOMEGAGIGA) { 1920384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%5s ","%s "), "pkts"); 1921384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%5s ","%s "), "bytes"); 1922384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 1923384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%8s ","%s "), "pkts"); 1924384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%10s ","%s "), "bytes"); 1925384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1926384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1927384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (!(format & FMT_NOTARGET)) 1928384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-9s ","%s "), "target"); 1929384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs(" prot ", stdout); 1930384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_OPTIONS) 1931384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso fputs("opt", stdout); 1932384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (format & FMT_VIA) { 1933384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-6s ","%s "), "in"); 1934384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT("%-6s ","%s "), "out"); 1935384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1936384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-19s ","%s "), "source"); 1937384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf(FMT(" %-19s "," %s "), "destination"); 1938384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 1939384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1940384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1941384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 1942b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka__nft_rule_list(struct nft_handle *h, const char *chain, const char *table, 1943384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format, 19448aa384a7d54734fd830840a2593cd4f07749976fTomasz Bursztyka void (*cb)(struct nft_rule *r, unsigned int num, 1945384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int format)) 1946384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 1947384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list *list; 1948384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule_list_iter *iter; 1949384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_rule *r; 1950384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rule_ctr = 0, ret = 0; 1951384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1952384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_rule_list_get(h); 1953b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (list == NULL) 1954384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 1955384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1956384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_rule_list_iter_create(list); 1957b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 1958b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 1959384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1960384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1961384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (r != NULL) { 1962384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_table = 1963384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE); 1964384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *rule_chain = 1965384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); 1966384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1967384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso rule_ctr++; 1968384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1969384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, rule_table) != 0 || 1970384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso strcmp(chain, rule_chain) != 0) 1971384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 1972384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 19730b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo if (rulenum > 0 && rule_ctr != rulenum) { 1974384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* List by rule number case */ 19750b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo goto next; 19760b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo } 1977384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 19788aa384a7d54734fd830840a2593cd4f07749976fTomasz Bursztyka cb(r, rule_ctr, format); 19790b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo if (rulenum > 0 && rule_ctr == rulenum) { 19800b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo ret = 1; 19810b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo break; 1982384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 19830b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo 1984384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 1985384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso r = nft_rule_list_iter_next(iter); 1986384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 1987384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1988384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_iter_destroy(iter); 1989b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 1990384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_rule_list_free(list); 1991384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1992384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == 0) 1993384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso errno = ENOENT; 1994384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1995384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret; 1996384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 1997384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 1998384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list(struct nft_handle *h, const char *chain, const char *table, 1999384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int rulenum, unsigned int format) 2000384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2001e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka const struct nft_family_ops *ops; 2002384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 2003384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2004384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 20050a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo bool found = false; 2006384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2007aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka /* If built-in chains don't exist for this table, create them */ 2008aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) 2009aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); 2010aa1601423175c90c37c3e6a3d6975d3e2eb74d1eTomasz Bursztyka 2011e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka ops = nft_family_ops_lookup(h->family); 2012e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka 2013b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka if (chain && rulenum) { 2014b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka __nft_rule_list(h, chain, table, 2015e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka rulenum, format, ops->print_firewall); 2016b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka return 1; 2017b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka } 2018b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka 2019384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2020384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2021384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2022b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2023b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2024384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2025384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2026384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2027384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2028384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2029384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2030384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2031384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2032384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 2033384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t refs = 2034384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_USE); 2035384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct xt_counters ctrs = { 2036384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .pcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS), 2037384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso .bcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES), 2038384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2039384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso bool basechain = false; 2040384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2041384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM)) 2042384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso basechain = true; 2043384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2044384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2045384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2046384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2047384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2048384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 20490a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo if (found) 20500a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf("\n"); 20510a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 20527a1026f59c101a67233c65dd5ef9b0ae15945ca5Tomasz Bursztyka print_header(format, chain_name, policy_name[policy], 20530b3bafcedff19b69ff5a51855da28e8e83c05b71Giuseppe Longo &ctrs, basechain, refs); 20547a1026f59c101a67233c65dd5ef9b0ae15945ca5Tomasz Bursztyka 2055b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka __nft_rule_list(h, chain_name, table, 2056e23e66f9d1a25c75df684850b7cd99053708c4d0Tomasz Bursztyka rulenum, format, ops->print_firewall); 20570a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 2058da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso /* we printed the chain we wanted, stop processing. */ 2059da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso if (chain) 2060da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso break; 2061da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso 20620a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo found = true; 20630a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo 2064384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2065384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2066384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2067384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 206834c59adfae98515468ec50c644c30115fee0b97eGiuseppe Longo nft_chain_list_iter_destroy(iter); 2069b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2070384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 2071384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2072384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2073384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2074384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2075384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic void 20768aa384a7d54734fd830840a2593cd4f07749976fTomasz Bursztykalist_save(struct nft_rule *r, unsigned int num, unsigned int format) 2077384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2078cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka struct iptables_command_state cs = {}; 2079cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 2080cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_to_iptables_command_state(r, &cs); 2081cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka 2082cdc78b1d6bd7b48ec05d78fc6e6cd98473f40357Tomasz Bursztyka nft_rule_print_save(&cs, r, NFT_RULE_APPEND, !(format & FMT_NOCOUNTS)); 2083384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2084384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2085384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusostatic int 20868dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayusonft_rule_list_chain_save(struct nft_handle *h, const char *chain, 20878dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso const char *table, struct nft_chain_list *list, 20888dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso int counters) 2089384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2090384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2091384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 2092384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2093384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2094b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2095384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2096384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2097384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2098384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2099384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2100384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2101384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2102384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2103384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t policy = 2104384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY); 2105384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 21068dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso if (strcmp(table, chain_table) != 0 || 21078dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso (chain && strcmp(chain, chain_name) != 0)) 2108384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2109384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2110384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* this is a base chain */ 21117244bef43f350ab31ef54db8a81905f6c68acac0Tomasz Bursztyka if (nft_chain_builtin(c)) { 2112384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-P %s %s", chain_name, policy_name[policy]); 2113384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2114384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (counters) { 21150a5f6c302f2f596f6e6aa0241a7772cf441b026fGiuseppe Longo printf(" -c %"PRIu64" %"PRIu64"\n", 2116384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS), 2117384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES)); 2118384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else 2119384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("\n"); 2120384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } else { 2121384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso printf("-N %s\n", chain_name); 2122384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2123384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2124384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2125384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2126384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2127e9a0ef8f1e27f5ef13a27f6cc984e8f2e05afd72Tomasz Bursztyka nft_chain_list_iter_destroy(iter); 2128e9a0ef8f1e27f5ef13a27f6cc984e8f2e05afd72Tomasz Bursztyka 2129384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 1; 2130384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2131384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2132384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_rule_list_save(struct nft_handle *h, const char *chain, 2133384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *table, int rulenum, int counters) 2134384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2135384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list *list; 2136384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain_list_iter *iter; 2137384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nft_chain *c; 213810f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso int ret = 1; 2139384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2140384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso list = nft_chain_dump(h); 2141384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2142384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Dump policies and custom chains first */ 214310f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso if (!rulenum) 21448dd2627afc462a2591c2f621743cae1a6b98d771Pablo Neira Ayuso nft_rule_list_chain_save(h, chain, table, list, counters); 2145384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2146384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* Now dump out rules in this table */ 2147384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso iter = nft_chain_list_iter_create(list); 2148b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2149b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2150384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2151384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2152384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso while (c != NULL) { 2153384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_table = 2154384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); 2155384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *chain_name = 2156384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); 2157384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2158384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (strcmp(table, chain_table) != 0) 2159384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2160384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (chain && strcmp(chain, chain_name) != 0) 2161384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto next; 2162384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2163b08836a33bac28860400e1e34c8244249f651a6fTomasz Bursztyka ret = __nft_rule_list(h, chain_name, table, rulenum, 216410f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso counters ? 0 : FMT_NOCOUNTS, list_save); 2165da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso 2166da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso /* we printed the chain we wanted, stop processing. */ 2167da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso if (chain) 2168da07c930b9e2aaf8df24022a175b1774aa0bdd8bPablo Neira Ayuso break; 2169384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusonext: 2170384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso c = nft_chain_list_iter_next(iter); 2171384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2172e9a0ef8f1e27f5ef13a27f6cc984e8f2e05afd72Tomasz Bursztyka 2173e9a0ef8f1e27f5ef13a27f6cc984e8f2e05afd72Tomasz Bursztyka nft_chain_list_iter_destroy(iter); 2174b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayusoerr: 2175384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nft_chain_list_free(list); 2176384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 217710f92fce0a2ea1805c8b269543b8f1738d22bf3dPablo Neira Ayuso return ret; 2178384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2179384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2180a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztykaint nft_rule_zero_counters(struct nft_handle *h, const char *chain, 2181a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka const char *table, int rulenum) 2182a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka{ 2183a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka struct iptables_command_state cs = {}; 2184a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka struct nft_rule_list *list; 2185a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka struct nft_rule *r; 2186a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka int ret = 0; 2187a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2188a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka nft_fn = nft_rule_delete; 2189a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2190a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka list = nft_rule_list_create(h); 2191a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka if (list == NULL) 2192a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka return 0; 2193a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2194e2a2c72277b49ac611809b3978365ab3010e1597Pablo Neira Ayuso r = nft_rule_find(h, list, chain, table, NULL, rulenum); 2195a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka if (r == NULL) { 2196a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka errno = ENOENT; 2197a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka ret = 1; 2198a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka goto error; 2199a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka } 2200a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2201a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka nft_rule_to_iptables_command_state(r, &cs); 2202a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2203a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka cs.counters.pcnt = cs.counters.bcnt = 0; 2204a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2205a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka ret = nft_rule_append(h, chain, table, &cs, 2206a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE), 2207a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka false); 2208a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2209a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztykaerror: 2210a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka nft_rule_list_destroy(list); 2211a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2212a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka return ret; 2213a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka} 2214a69cc575295eedb44f0fa33cd5fcf1cc0114133aTomasz Bursztyka 2215d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayusostatic int nft_action(struct nft_handle *h, int action) 22169e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 2217d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso int flags = NLM_F_CREATE, type; 2218d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso struct rule_update *n, *tmp; 22199e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso struct nlmsghdr *nlh; 2220d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso uint32_t seq = 1; 22219e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso int ret; 22229e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2223d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nft_batch_begin(h->batch, seq++); 22249e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2225d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso list_for_each_entry_safe(n, tmp, &h->rule_list, head) { 2226d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso switch (n->type) { 2227d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso case NFT_DO_APPEND: 2228d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso type = NFT_MSG_NEWRULE; 2229d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso flags |= NLM_F_APPEND; 2230d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2231d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso case NFT_DO_INSERT: 2232d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso type = NFT_MSG_NEWRULE; 2233d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2234d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso case NFT_DO_REPLACE: 2235d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso type = NFT_MSG_NEWRULE; 2236d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso flags |= NLM_F_REPLACE; 2237d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2238d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso case NFT_DO_DELETE: 2239d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso case NFT_DO_FLUSH: 2240d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso type = NFT_MSG_DELRULE; 2241d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2242d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso default: 2243d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return 0; 2244d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 22459e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2246d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch), 2247d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso type, h->family, flags, seq++); 2248d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_nlmsg_build_payload(nlh, n->rule); 2249d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_print_debug(n->rule, nlh); 2250d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2251d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso h->rule_list_num--; 2252d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso list_del(&n->head); 2253d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso nft_rule_free(n->rule); 2254d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso free(n); 2255d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2256d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (!mnl_nlmsg_batch_next(h->batch)) 2257d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso h->batch = mnl_nft_batch_page_add(h->batch); 2258d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso } 2259d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2260d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso switch (action) { 2261d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso case NFT_DO_COMMIT: 2262d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nft_batch_end(h->batch, seq++); 2263d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 2264d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso case NFT_DO_ABORT: 2265d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso break; 22669e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso } 2267d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2268d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (!mnl_nlmsg_batch_is_empty(h->batch)) 2269d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso h->batch = mnl_nft_batch_page_add(h->batch); 2270d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2271d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso ret = mnl_nft_batch_talk(h); 2272d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso if (ret < 0) 2273d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso perror("mnl_nft_batch_talk:"); 2274d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2275d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso mnl_nlmsg_batch_reset(h->batch); 2276d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso 2277f041efe3c26e3059df1ac8f1775f77423d4be5f6Pablo Neira Ayuso return ret == 0 ? 1 : 0; 22789e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 22799e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 22809e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayusoint nft_commit(struct nft_handle *h) 22819e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 2282d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return nft_action(h, NFT_DO_COMMIT); 22839e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 22849e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 22859e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayusoint nft_abort(struct nft_handle *h) 22869e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso{ 2287d6a127cd5710f8c60e95bfd0378ca352c07140a9Pablo Neira Ayuso return nft_action(h, NFT_DO_ABORT); 22889e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso} 22899e62dc8637f210cdeaed784396fecab9b6e5f043Pablo Neira Ayuso 2290384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoint nft_compatible_revision(const char *name, uint8_t rev, int opt) 2291384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2292384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct mnl_socket *nl; 2293384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso char buf[MNL_SOCKET_BUFFER_SIZE]; 2294384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nlmsghdr *nlh; 2295384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso uint32_t portid, seq, type; 2296384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int ret = 0; 2297384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 229885512f09680a798ebe92e96ad62eeae863fbc791Pablo Neira Ayuso if (opt == IPT_SO_GET_REVISION_MATCH || 229985512f09680a798ebe92e96ad62eeae863fbc791Pablo Neira Ayuso opt == IP6T_SO_GET_REVISION_MATCH) 2300384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 0; 2301384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso else 2302384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso type = 1; 2303384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2304384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh = mnl_nlmsg_put_header(buf); 2305384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET; 2306384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 2307384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nlh->nlmsg_seq = seq = time(NULL); 2308384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2309384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); 2310384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->nfgen_family = AF_INET; 2311384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->version = NFNETLINK_V0; 2312384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nfg->res_id = 0; 2313384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2314384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_strz(nlh, NFTA_COMPAT_NAME, name); 2315384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_REV, htonl(rev)); 2316384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_attr_put_u32(nlh, NFTA_COMPAT_TYPE, htonl(type)); 2317384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2318384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso DEBUGP("requesting `%s' rev=%d type=%d via nft_compat\n", 2319384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso name, rev, type); 2320384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2321384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso nl = mnl_socket_open(NETLINK_NETFILTER); 2322384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (nl == NULL) { 2323384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_open"); 2324384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return 0; 2325384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2326384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2327384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { 2328384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_bind"); 2329384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2330384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2331384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso portid = mnl_socket_get_portid(nl); 2332384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2333384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { 2334384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_send"); 2335384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2336384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2337384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2338384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); 2339384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 2340384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_socket_recvfrom"); 2341384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2342384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2343384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2344384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); 2345384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if (ret == -1) { 2346384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso perror("mnl_cb_run"); 2347384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso goto err; 2348384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2349384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2350384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoerr: 2351384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso mnl_socket_close(nl); 2352384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2353384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return ret < 0 ? 0 : 1; 2354384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 2355384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2356384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* Translates errno numbers into more human-readable form than strerror. */ 2357384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayusoconst char *nft_strerror(int err) 2358384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso{ 2359384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso unsigned int i; 2360384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso static struct table_struct { 2361384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso void *fn; 2362384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso int err; 2363384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso const char *message; 2364384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } table[] = 2365384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { 2366384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, ENOTEMPTY, "Chain is not empty" }, 2367384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EINVAL, "Can't delete built-in chain" }, 2368384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_del, EMLINK, 2369384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Can't delete chain with references left" }, 2370384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_user_add, EEXIST, "Chain already exists" }, 2371384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, E2BIG, "Index of insertion too big" }, 2372384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_replace, E2BIG, "Index of replacement too big" }, 2373384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete_num, E2BIG, "Index of deletion too big" }, 2374384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso/* { TC_READ_COUNTER, E2BIG, "Index of counter too big" }, 2375384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */ 2376384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, ELOOP, "Loop found in table" }, 2377384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_add, EINVAL, "Target problem" }, 2378384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso /* ENOENT for DELETE probably means no matching rule */ 2379384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_rule_delete, ENOENT, 2380384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso "Bad rule (does a matching rule exist in that chain?)" }, 2381384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, ENOENT, "Bad built-in chain name" }, 2382384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { nft_chain_set, EINVAL, "Bad policy name" }, 2383384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, EPERM, "Permission denied (you must be root)" }, 2384384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, 0, "Incompatible with this kernel" }, 2385384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" }, 2386384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOSYS, "Will be implemented real soon. I promise ;)" }, 2387384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOMEM, "Memory allocation problem" }, 2388384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso { NULL, ENOENT, "No chain/target/match by that name" }, 2389384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso }; 2390384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2391384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) { 2392384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso if ((!table[i].fn || table[i].fn == nft_fn) 2393384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso && table[i].err == err) 2394384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return table[i].message; 2395384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso } 2396384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso 2397384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso return strerror(err); 2398384958620abab397062b67fb2763e813b63f74f0Pablo Neira Ayuso} 23998b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 24008b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayusostatic void xtables_config_perror(uint32_t flags, const char *fmt, ...) 24018b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso{ 24028b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_list args; 24038b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 24048b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_start(args, fmt); 24058b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 24068b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (flags & NFT_LOAD_VERBOSE) 24078b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso vfprintf(stderr, fmt, args); 24088b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 24098b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso va_end(args); 24108b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso} 24118b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 24128b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayusoint nft_xtables_config_load(struct nft_handle *h, const char *filename, 24138b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso uint32_t flags) 24148b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso{ 24158b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_table_list *table_list = nft_table_list_alloc(); 24168b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_chain_list *chain_list = nft_chain_list_alloc(); 24176a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey struct nft_table_list_iter *titer = NULL; 24186a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey struct nft_chain_list_iter *citer = NULL; 24198b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_table *table; 24208b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso struct nft_chain *chain; 2421cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo uint32_t table_family, chain_family; 2422cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo bool found = false; 24238b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 2424e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka if (h->restore) 2425e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka return 0; 2426e6b8e172fca48f5d80699afe80947b0fc1f23fd6Tomasz Bursztyka 24278b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (xtables_config_parse(filename, table_list, chain_list) < 0) { 24288b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == ENOENT) { 24298b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 24308b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "configuration file `%s' does not exists\n", 24318b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso filename); 24328b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 24338b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 24348b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "Fatal error parsing config file: %s\n", 24358b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 24368b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 24376a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 24388b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 24398b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 24408b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso /* Stage 1) create tables */ 24418b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso titer = nft_table_list_iter_create(table_list); 24428b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso while ((table = nft_table_list_iter_next(titer)) != NULL) { 2443cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo table_family = nft_table_attr_get_u32(table, 2444cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo NFT_TABLE_ATTR_FAMILY); 2445cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo if (h->family != table_family) 2446cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo continue; 2447cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 2448cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo found = true; 2449cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 24508b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_table_add(h, table) < 0) { 24518b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == EEXIST) { 24528b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 24538b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "table `%s' already exists, skipping\n", 24548b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME)); 24558b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 24568b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 24578b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "table `%s' cannot be create, reason `%s'. Exitting\n", 24588b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME), 24598b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 24606a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 24618b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 24628b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso continue; 24638b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 24648b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, "table `%s' has been created\n", 24658b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME)); 24668b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 24672c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_table_list_iter_destroy(titer); 24682c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_table_list_free(table_list); 24698b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 2470cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo if (!found) 24716a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 2472cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 24738b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso /* Stage 2) create chains */ 24748b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso citer = nft_chain_list_iter_create(chain_list); 24758b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso while ((chain = nft_chain_list_iter_next(citer)) != NULL) { 2476cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo chain_family = nft_chain_attr_get_u32(chain, 2477cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo NFT_CHAIN_ATTR_TABLE); 2478cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo if (h->family != chain_family) 2479cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo continue; 2480cea310bd1d078618e87b83410f8c6f75b34de450Giuseppe Longo 24818b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (nft_chain_add(h, chain) < 0) { 24828b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso if (errno == EEXIST) { 24838b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 24848b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' already exists in table `%s', skipping\n", 24858b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME), 24868b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE)); 24878b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } else { 24888b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 24898b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' cannot be create, reason `%s'. Exitting\n", 24908b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME), 24918b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso strerror(errno)); 24926a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey goto err; 24938b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 24948b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso continue; 24958b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 24968b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso 24978b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso xtables_config_perror(flags, 24988b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso "chain `%s' in table `%s' has been created\n", 24998b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME), 25008b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso (char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE)); 25018b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso } 25022c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_chain_list_iter_destroy(citer); 25032c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso nft_chain_list_free(chain_list); 25042c5850147937cd3da104adf654cc7b2d1f0c0a0bPablo Neira Ayuso 25058b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso return 0; 25066a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey 25076a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Reyerr: 25086a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey nft_table_list_free(table_list); 25096a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey nft_chain_list_free(chain_list); 25106a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey 25116a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey if (titer != NULL) 25126a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey nft_table_list_iter_destroy(titer); 25136a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey if (citer != NULL) 2514504119fe14bffde5800a631da89b80ed6043cecbPablo Neira Ayuso nft_chain_list_iter_destroy(citer); 25156a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey 25166a4033b70dfdcc2df66f4ea51c901786a2b6131cAna Rey return -1; 25178b9ea2e3f8d685a6b940691cabf5e82c96254747Pablo Neira Ayuso} 2518b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2519b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longoint nft_chain_zero_counters(struct nft_handle *h, const char *chain, 2520b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *table) 2521b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo{ 2522b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nft_chain_list *list; 2523b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nft_chain_list_iter *iter; 2524b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nft_chain *c; 2525b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo struct nlmsghdr *nlh; 2526b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo char buf[MNL_SOCKET_BUFFER_SIZE]; 2527b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo int ret = 0; 2528b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2529b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo list = nft_chain_list_get(h); 2530b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (list == NULL) 2531b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto err; 2532b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2533b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo iter = nft_chain_list_iter_create(list); 2534b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso if (iter == NULL) 2535b6d90619891e9a2f804af6af9860da8f95878abfPablo Neira Ayuso goto err; 2536b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2537b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo c = nft_chain_list_iter_next(iter); 2538b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo while (c != NULL) { 2539b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *chain_name = 2540b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_get(c, NFT_CHAIN_ATTR_NAME); 2541b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo const char *chain_table = 2542b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_get(c, NFT_CHAIN_ATTR_TABLE); 2543b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2544b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (strcmp(table, chain_table) != 0) 2545b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto next; 2546b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2547b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (chain != NULL && strcmp(chain, chain_name) != 0) 2548b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo goto next; 2549b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2550b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, 0); 2551b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, 0); 2552b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2553b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_attr_unset(c, NFT_CHAIN_ATTR_HANDLE); 2554b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2555b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, 2556b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo h->family, NLM_F_ACK, h->seq); 2557b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2558b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_nlmsg_build_payload(nlh, c); 2559b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2560b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo ret = mnl_talk(h, nlh, NULL, NULL); 2561b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo if (ret < 0) 2562b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo perror("mnl_talk:nft_chain_zero_counters"); 2563b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 256436ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo if (chain != NULL) 256536ca9bdb288f7ba528307b7695ab94f7fa8e9a2dGiuseppe Longo break; 2566b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longonext: 2567b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo c = nft_chain_list_iter_next(iter); 2568b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo } 2569b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2570b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_list_iter_destroy(iter); 2571b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2572b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longoerr: 2573b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo nft_chain_list_free(list); 2574b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo 2575b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo /* the core expects 1 for success and 0 for error */ 2576b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo return ret == 0 ? 1 : 0; 2577b48126ca92cc44e88aa024e6da7ff245914d6a53Giuseppe Longo} 2578