#ifdef CONFIG_NF_CT_PROTO_SCTP
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp;
#endif
-#ifdef CONFIG_NF_CT_PROTO_UDPLITE
-extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite;
-#endif
#ifdef CONFIG_NF_CT_PROTO_GRE
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre;
#endif
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
const struct nf_hook_state *state);
-int nf_conntrack_udplite_packet(struct nf_conn *ct,
- struct sk_buff *skb,
- unsigned int dataoff,
- enum ip_conntrack_info ctinfo,
- const struct nf_hook_state *state);
int nf_conntrack_tcp_packet(struct nf_conn *ct,
struct sk_buff *skb,
unsigned int dataoff,
/* Existing built-in generic protocol */
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
-#define MAX_NF_CT_PROTO IPPROTO_UDPLITE
-
const struct nf_conntrack_l4proto *nf_ct_l4proto_find(u8 l4proto);
/* Generic netlink helpers */
If unsure, say Y.
-config NF_CT_PROTO_UDPLITE
- bool 'UDP-Lite protocol connection tracking support'
- depends on NETFILTER_ADVANCED
- default y
- help
- With this option enabled, the layer 3 independent connection
- tracking code will be able to do state tracking on UDP-Lite
- connections.
-
- If unsure, say Y.
-
config NF_CONNTRACK_AMANDA
tristate "Amanda backup protocol support"
depends on NETFILTER_ADVANCED
#endif
case IPPROTO_TCP:
case IPPROTO_UDP:
-#ifdef CONFIG_NF_CT_PROTO_UDPLITE
- case IPPROTO_UDPLITE:
-#endif
#ifdef CONFIG_NF_CT_PROTO_SCTP
case IPPROTO_SCTP:
#endif
case IPPROTO_ICMPV6:
return nf_conntrack_icmpv6_packet(ct, skb, ctinfo, state);
#endif
-#ifdef CONFIG_NF_CT_PROTO_UDPLITE
- case IPPROTO_UDPLITE:
- return nf_conntrack_udplite_packet(ct, skb, dataoff,
- ctinfo, state);
-#endif
#ifdef CONFIG_NF_CT_PROTO_SCTP
case IPPROTO_SCTP:
return nf_conntrack_sctp_packet(ct, skb, dataoff,
#ifdef CONFIG_NF_CT_PROTO_SCTP
case IPPROTO_SCTP: return &nf_conntrack_l4proto_sctp;
#endif
-#ifdef CONFIG_NF_CT_PROTO_UDPLITE
- case IPPROTO_UDPLITE: return &nf_conntrack_l4proto_udplite;
-#endif
#ifdef CONFIG_NF_CT_PROTO_GRE
case IPPROTO_GRE: return &nf_conntrack_l4proto_gre;
#endif
return NF_ACCEPT;
}
-#ifdef CONFIG_NF_CT_PROTO_UDPLITE
-static void udplite_error_log(const struct sk_buff *skb,
- const struct nf_hook_state *state,
- const char *msg)
-{
- nf_l4proto_log_invalid(skb, state, IPPROTO_UDPLITE, "%s", msg);
-}
-
-static bool udplite_error(struct sk_buff *skb,
- unsigned int dataoff,
- const struct nf_hook_state *state)
-{
- unsigned int udplen = skb->len - dataoff;
- const struct udphdr *hdr;
- struct udphdr _hdr;
- unsigned int cscov;
-
- /* Header is too small? */
- hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
- if (!hdr) {
- udplite_error_log(skb, state, "short packet");
- return true;
- }
-
- cscov = ntohs(hdr->len);
- if (cscov == 0) {
- cscov = udplen;
- } else if (cscov < sizeof(*hdr) || cscov > udplen) {
- udplite_error_log(skb, state, "invalid checksum coverage");
- return true;
- }
-
- /* UDPLITE mandates checksums */
- if (!hdr->check) {
- udplite_error_log(skb, state, "checksum missing");
- return true;
- }
-
- /* Checksum invalid? Ignore. */
- if (state->hook == NF_INET_PRE_ROUTING &&
- state->net->ct.sysctl_checksum &&
- nf_checksum_partial(skb, state->hook, dataoff, cscov, IPPROTO_UDP,
- state->pf)) {
- udplite_error_log(skb, state, "bad checksum");
- return true;
- }
-
- return false;
-}
-
-/* Returns verdict for packet, and may modify conntracktype */
-int nf_conntrack_udplite_packet(struct nf_conn *ct,
- struct sk_buff *skb,
- unsigned int dataoff,
- enum ip_conntrack_info ctinfo,
- const struct nf_hook_state *state)
-{
- unsigned int *timeouts;
-
- if (udplite_error(skb, dataoff, state))
- return -NF_ACCEPT;
-
- timeouts = nf_ct_timeout_lookup(ct);
- if (!timeouts)
- timeouts = udp_get_timeouts(nf_ct_net(ct));
-
- /* If we've seen traffic both ways, this is some kind of UDP
- stream. Extend timeout. */
- if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
- nf_ct_refresh_acct(ct, ctinfo, skb,
- timeouts[UDP_CT_REPLIED]);
-
- if (unlikely((ct->status & IPS_NAT_CLASH)))
- return NF_ACCEPT;
-
- /* Also, more likely to be important, and not a probe */
- if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
- nf_conntrack_event_cache(IPCT_ASSURED, ct);
- } else {
- nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[UDP_CT_UNREPLIED]);
- }
- return NF_ACCEPT;
-}
-#endif
-
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
#include <linux/netfilter/nfnetlink.h>
},
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
};
-
-#ifdef CONFIG_NF_CT_PROTO_UDPLITE
-const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite =
-{
- .l4proto = IPPROTO_UDPLITE,
- .allow_clash = true,
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
- .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
- .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
- .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
- .nla_policy = nf_ct_port_nla_policy,
-#endif
-#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
- .ctnl_timeout = {
- .nlattr_to_obj = udp_timeout_nlattr_to_obj,
- .obj_to_nlattr = udp_timeout_obj_to_nlattr,
- .nlattr_max = CTA_TIMEOUT_UDP_MAX,
- .obj_size = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
- .nla_policy = udp_timeout_nla_policy,
- },
-#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
-};
-#endif
ntohs(tuple->src.u.tcp.port),
ntohs(tuple->dst.u.tcp.port));
break;
- case IPPROTO_UDPLITE:
case IPPROTO_UDP:
seq_printf(s, "sport=%hu dport=%hu ",
ntohs(tuple->src.u.udp.port),
case IPPROTO_UDP: return "udp";
case IPPROTO_GRE: return "gre";
case IPPROTO_SCTP: return "sctp";
- case IPPROTO_UDPLITE: return "udplite";
case IPPROTO_ICMPV6: return "icmpv6";
}
fl4->daddr = t->dst.u3.ip;
if (t->dst.protonum == IPPROTO_TCP ||
t->dst.protonum == IPPROTO_UDP ||
- t->dst.protonum == IPPROTO_UDPLITE ||
t->dst.protonum == IPPROTO_SCTP)
fl4->fl4_dport = t->dst.u.all;
}
fl4->saddr = t->src.u3.ip;
if (t->dst.protonum == IPPROTO_TCP ||
t->dst.protonum == IPPROTO_UDP ||
- t->dst.protonum == IPPROTO_UDPLITE ||
t->dst.protonum == IPPROTO_SCTP)
fl4->fl4_sport = t->src.u.all;
}
fl6->daddr = t->dst.u3.in6;
if (t->dst.protonum == IPPROTO_TCP ||
t->dst.protonum == IPPROTO_UDP ||
- t->dst.protonum == IPPROTO_UDPLITE ||
t->dst.protonum == IPPROTO_SCTP)
fl6->fl6_dport = t->dst.u.all;
}
fl6->saddr = t->src.u3.in6;
if (t->dst.protonum == IPPROTO_TCP ||
t->dst.protonum == IPPROTO_UDP ||
- t->dst.protonum == IPPROTO_UDPLITE ||
t->dst.protonum == IPPROTO_SCTP)
fl6->fl6_sport = t->src.u.all;
}
case IPPROTO_GRE: /* all fall though */
case IPPROTO_TCP:
case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
case IPPROTO_SCTP:
if (maniptype == NF_NAT_MANIP_SRC)
port = tuple->src.u.all;
goto find_free_id;
#endif
case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
case IPPROTO_TCP:
case IPPROTO_SCTP:
if (maniptype == NF_NAT_MANIP_SRC)
return true;
}
-static bool udplite_manip_pkt(struct sk_buff *skb,
- unsigned int iphdroff, unsigned int hdroff,
- const struct nf_conntrack_tuple *tuple,
- enum nf_nat_manip_type maniptype)
-{
-#ifdef CONFIG_NF_CT_PROTO_UDPLITE
- struct udphdr *hdr;
-
- if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
- return false;
-
- hdr = (struct udphdr *)(skb->data + hdroff);
- __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, true);
-#endif
- return true;
-}
-
static bool
sctp_manip_pkt(struct sk_buff *skb,
unsigned int iphdroff, unsigned int hdroff,
case IPPROTO_UDP:
return udp_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype);
- case IPPROTO_UDPLITE:
- return udplite_manip_pkt(skb, iphdroff, hdroff,
- tuple, maniptype);
case IPPROTO_SCTP:
return sctp_manip_pkt(skb, iphdroff, hdroff,
tuple, maniptype);
timeouts = nf_tcp_pernet(info->net)->timeouts;
break;
case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
timeouts = nf_udp_pernet(info->net)->timeouts;
break;
case IPPROTO_ICMPV6:
switch (priv->l4proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
case IPPROTO_DCCP:
case IPPROTO_SCTP:
break;