linux/net/netfilter/nf_nat_proto_udplite.c
<<
>>
Prefs
   1/* (C) 1999-2001 Paul `Rusty' Russell
   2 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
   3 * (C) 2008 Patrick McHardy <kaber@trash.net>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 */
   9
  10#include <linux/types.h>
  11#include <linux/init.h>
  12#include <linux/udp.h>
  13
  14#include <linux/netfilter.h>
  15#include <linux/module.h>
  16#include <net/netfilter/nf_nat.h>
  17#include <net/netfilter/nf_nat_l3proto.h>
  18#include <net/netfilter/nf_nat_l4proto.h>
  19
  20static u16 udplite_port_rover;
  21
  22static void
  23udplite_unique_tuple(const struct nf_nat_l3proto *l3proto,
  24                     struct nf_conntrack_tuple *tuple,
  25                     const struct nf_nat_range *range,
  26                     enum nf_nat_manip_type maniptype,
  27                     const struct nf_conn *ct)
  28{
  29        nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct,
  30                                    &udplite_port_rover);
  31}
  32
  33static bool
  34udplite_manip_pkt(struct sk_buff *skb,
  35                  const struct nf_nat_l3proto *l3proto,
  36                  unsigned int iphdroff, unsigned int hdroff,
  37                  const struct nf_conntrack_tuple *tuple,
  38                  enum nf_nat_manip_type maniptype)
  39{
  40        struct udphdr *hdr;
  41        __be16 *portptr, newport;
  42
  43        if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
  44                return false;
  45
  46        hdr = (struct udphdr *)(skb->data + hdroff);
  47
  48        if (maniptype == NF_NAT_MANIP_SRC) {
  49                /* Get rid of source port */
  50                newport = tuple->src.u.udp.port;
  51                portptr = &hdr->source;
  52        } else {
  53                /* Get rid of dst port */
  54                newport = tuple->dst.u.udp.port;
  55                portptr = &hdr->dest;
  56        }
  57
  58        l3proto->csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
  59        inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, 0);
  60        if (!hdr->check)
  61                hdr->check = CSUM_MANGLED_0;
  62
  63        *portptr = newport;
  64        return true;
  65}
  66
  67static const struct nf_nat_l4proto nf_nat_l4proto_udplite = {
  68        .l4proto                = IPPROTO_UDPLITE,
  69        .manip_pkt              = udplite_manip_pkt,
  70        .in_range               = nf_nat_l4proto_in_range,
  71        .unique_tuple           = udplite_unique_tuple,
  72#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
  73        .nlattr_to_range        = nf_nat_l4proto_nlattr_to_range,
  74#endif
  75};
  76
  77static int __init nf_nat_proto_udplite_init(void)
  78{
  79        int err;
  80
  81        err = nf_nat_l4proto_register(NFPROTO_IPV4, &nf_nat_l4proto_udplite);
  82        if (err < 0)
  83                goto err1;
  84        err = nf_nat_l4proto_register(NFPROTO_IPV6, &nf_nat_l4proto_udplite);
  85        if (err < 0)
  86                goto err2;
  87        return 0;
  88
  89err2:
  90        nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_udplite);
  91err1:
  92        return err;
  93}
  94
  95static void __exit nf_nat_proto_udplite_fini(void)
  96{
  97        nf_nat_l4proto_unregister(NFPROTO_IPV6, &nf_nat_l4proto_udplite);
  98        nf_nat_l4proto_unregister(NFPROTO_IPV4, &nf_nat_l4proto_udplite);
  99}
 100
 101module_init(nf_nat_proto_udplite_init);
 102module_exit(nf_nat_proto_udplite_fini);
 103
 104MODULE_LICENSE("GPL");
 105MODULE_DESCRIPTION("UDP-Lite NAT protocol helper");
 106MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 107