-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Apress
committed
Oct 18, 2016
0 parents
commit 65c2457
Showing
14 changed files
with
6,071 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
chapter 1 | ||
---------- | ||
|
||
struct net_device { | ||
unsigned int irq; /* device IRQ number */ | ||
. . . | ||
const struct net_device_ops *netdev_ops; | ||
. . . | ||
unsigned int mtu; | ||
. . . | ||
unsigned int promiscuity; | ||
. . . | ||
unsigned char *dev_addr; | ||
. . . | ||
}; | ||
(include/linux/netdevice.h) | ||
|
||
struct sk_buff { | ||
. . . | ||
struct sock *sk; | ||
struct net_device *dev; | ||
. . . | ||
_u8 pkt_type:3, | ||
. . . | ||
_be16 protocol; | ||
. . . | ||
sk_buff_data_t tail; | ||
sk_buff_data_t end; | ||
unsigned char *head, | ||
*data; | ||
sk_buff_data_t transport_header; | ||
sk_buff_data_t network_header; | ||
sk_buff_data_t mac_header; | ||
. . . | ||
}; | ||
(include/linux/skbuff.h) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
chapter 10 | ||
----------- | ||
|
||
struct netns_xfrm { | ||
struct hlist_head *state_bydst; | ||
struct hlist_head *state_bysrc; | ||
struct hlist_head *state_byspi; | ||
. . . | ||
unsigned int state_num; | ||
. . . | ||
struct work_struct state_gc_work; | ||
. . . | ||
u32 sysctl_aevent_etime; | ||
u32 sysctl_aevent_rseqth; | ||
int sysctl_larval_drop; | ||
u32 sysctl_acq_expires; | ||
}; | ||
(include/net/netns/xfrm.h) | ||
|
||
static int __net_init xfrm_user_net_init(struct net *net) | ||
{ | ||
struct sock *nlsk; | ||
struct netlink_kernel_cfg cfg = { | ||
.groups = XFRMNLGRP_MAX, | ||
.input = xfrm_netlink_rcv, | ||
}; | ||
nlsk = netlink_kernel_create(net, NETLINK_XFRM, &cfg); | ||
. . . | ||
return 0; | ||
} | ||
|
||
struct xfrm_selector { | ||
xfrm_address_t daddr; | ||
xfrm_address_t saddr; | ||
_be16 dport; | ||
_be16 dport_mask; | ||
_be16 sport; | ||
_be16 sport_mask; | ||
_u16 family; | ||
_u8 prefixlen_d; | ||
_u8 prefixlen_s; | ||
_u8 proto; | ||
int ifindex; | ||
_kernel_uid32_t user; | ||
}; | ||
|
||
(include/uapi/linux/xfrm.h) | ||
|
||
struct xfrm_policy { | ||
. . . | ||
struct hlist_node bydst; | ||
struct hlist_node byidx; | ||
/* This lock only affects elements except for entry. */ | ||
rwlock_t lock; | ||
atomic_t refcnt; | ||
struct timer_list timer; | ||
struct flow_cache_object flo; | ||
atomic_t genid; | ||
u32 priority; | ||
u32 index; | ||
struct xfrm_mark mark; | ||
struct xfrm_selector selector; | ||
struct xfrm_lifetime_cfg lft; | ||
struct xfrm_lifetime_cur curlft; | ||
struct xfrm_policy_walk_entry walk; | ||
struct xfrm_policy_queue polq; | ||
u8 type; | ||
u8 action; | ||
u8 flags; | ||
u8 xfrm_nr; | ||
u16 family; | ||
struct xfrm_sec_ctx *security; | ||
struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; | ||
}; | ||
(include/net/xfrm.h) | ||
|
||
struct xfrm_state { | ||
. . . | ||
union { | ||
struct hlist_node gclist; | ||
struct hlist_node bydst; | ||
}; | ||
struct hlist_node bysrc; | ||
struct hlist_node byspi; | ||
atomic_t refcnt; | ||
spinlock_t lock; | ||
struct xfrm_id id; | ||
struct xfrm_selector sel; | ||
struct xfrm_mark mark; | ||
u32 tfcpad; | ||
u32 genid; | ||
/* Key manager bits */ | ||
struct xfrm_state_walk km; | ||
/* Parameters of this state. */ | ||
struct { | ||
u32 reqid; | ||
u8 mode; | ||
u8 replay_window; | ||
u8 aalgo, ealgo, calgo; | ||
u8 flags; | ||
u16 family; | ||
xfrm_address_t saddr; | ||
int header_len; | ||
int trailer_len; | ||
} props; | ||
struct xfrm_lifetime_cfg lft; | ||
/* Data for transformer */ | ||
struct xfrm_algo_auth *aalg; | ||
struct xfrm_algo *ealg; | ||
struct xfrm_algo *calg; | ||
struct xfrm_algo_aead *aead; | ||
/* Data for encapsulator */ | ||
struct xfrm_encap_tmpl *encap; | ||
/* Data for care-of address */ | ||
xfrm_address_t *coaddr; | ||
/* IPComp needs an IPIP tunnel for handling uncompressed packets */ | ||
struct xfrm_state *tunnel; | ||
/* If a tunnel, number of users + 1 */ | ||
atomic_t tunnel_users; | ||
/* State for replay detection */ | ||
struct xfrm_replay_state replay; | ||
struct xfrm_replay_state_esn *replay_esn; | ||
/* Replay detection state at the time we sent the last notification */ | ||
struct xfrm_replay_state preplay; | ||
struct xfrm_replay_state_esn *preplay_esn; | ||
/* The functions for replay detection. */ | ||
struct xfrm_replay *reply; | ||
/* internal flag that only holds state for delayed aevent at the | ||
* moment | ||
*/ | ||
u32 xflags; | ||
/* Replay detection notification settings */ | ||
u32 replay_maxage; | ||
u32 replay_maxdiff; | ||
/* Replay detection notification timer */ | ||
struct timer_list rtimer; | ||
/* Statistics */ | ||
struct xfrm_stats stats; | ||
struct xfrm_lifetime_cur curlft; | ||
struct tasklet_hrtimer mtimer; | ||
/* used to fix curlft->add_time when changing date */ | ||
long saved_tmo; | ||
/* Last used time */ | ||
unsigned long lastused; | ||
/* Reference to data common to all the instances of this | ||
* transformer. */ | ||
const struct xfrm_type *type; | ||
struct xfrm_mode *inner_mode; | ||
struct xfrm_mode *inner_mode_iaf; | ||
struct xfrm_mode *outer_mode; | ||
/* Security context */ | ||
struct xfrm_sec_ctx *security; | ||
/* Private data of this transformer, format is opaque, | ||
* interpreted by xfrm_type methods. */ | ||
void *data; | ||
}; | ||
(include/net/xfrm.h) | ||
|
||
static const struct xfrm_type esp_type = | ||
{ | ||
.description = "ESP4", | ||
.owner = THIS_MODULE, | ||
.proto = IPPROTO_ESP, | ||
.flags = XFRM_TYPE_REPLAY_PROT, | ||
.init_state = esp_init_state, | ||
.destructor = esp_destroy, | ||
.get_mtu = esp4_get_mtu, | ||
.input = esp_input, | ||
.output = esp_output | ||
}; | ||
|
||
static const struct net_protocol esp4_protocol = { | ||
.handler = xfrm4_rcv, | ||
.err_handler = esp4_err, | ||
.no_policy = 1, | ||
.netns_ok = 1, | ||
}; | ||
|
||
static int __init esp4_init(void) | ||
{ | ||
if (xfrm_register_type(&esp_type, AF_INET) < 0) { | ||
pr_info("%s: can't add xfrm type\n", __func__); | ||
return -EAGAIN; | ||
} | ||
if (inet_add_protocol(&esp4_protocol, IPPROTO_ESP) < 0) { | ||
pr_info("%s: can't add protocol\n", __func__); | ||
xfrm_unregister_type(&esp_type, AF_INET); | ||
return -EAGAIN; | ||
} | ||
return 0; | ||
} | ||
(net/ipv4/esp4.c) | ||
|
||
int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | ||
{ | ||
struct xfrm_state *x; | ||
do { | ||
. . . | ||
x = xfrm_state_lookup(net, skb->mark, daddr, spi, nexthdr, family); | ||
|
||
if (x == NULL) { | ||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); | ||
xfrm_audit_state_notfound(skb, family, spi, seq); | ||
goto drop; | ||
} | ||
|
||
nexthdr = x->type->input(x, skb); | ||
XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; | ||
|
||
. . . | ||
_skb_push(skb, skb->data - skb_network_header(skb)); | ||
iph->tot_len = htons(skb->len); | ||
ip_send_check(iph); | ||
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, | ||
xfrm4_rcv_encap_finish); | ||
return 0; | ||
} | ||
|
||
int xfrm4_transport_finish(struct sk_buff *skb, int async) | ||
{ | ||
struct iphdr *iph = ip_hdr(skb); | ||
. . . | ||
iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol; | ||
. . . | ||
} | ||
|
||
struct xfrm_dst { | ||
union { | ||
struct dst_entry dst; | ||
struct rtable rt; | ||
struct rt6_info rt6; | ||
} u; | ||
struct dst_entry *route; | ||
struct flow_cache_object flo; | ||
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; | ||
int num_pols, num_xfrms; | ||
#ifdef CONFIG_XFRM_SUB_POLICY | ||
struct flowi *origin; | ||
struct xfrm_selector *partner; | ||
#endif | ||
u32 xfrm_genid; | ||
u32 policy_genid; | ||
u32 route_mtu_cached; | ||
u32 child_mtu_cached; | ||
u32 route_cookie; | ||
u32 path_cookie; | ||
}; | ||
(include/net/xfrm.h) | ||
|
||
struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | ||
const struct flowi *fl, struct sock *sk, int flags) | ||
{ | ||
u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); | ||
if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { | ||
num_pols = 1; | ||
pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); | ||
. . . | ||
flo = flow_cache_lookup(net, fl, family, dir, xfrm_bundle_lookup, dst_orig); | ||
xdst = container_of(flo, struct xfrm_dst, flo); | ||
num_pols = xdst->num_pols; | ||
num_xfrms = xdst->num_xfrms; | ||
memcpy(pols, xdst->pols, sizeof(struct xfrm_policy*) * num_pols); | ||
route = xdst->route; | ||
} | ||
dst = &xdst->u.dst; | ||
if (route == NULL && num_xfrms > 0) { | ||
/* The only case when xfrm_bundle_lookup() returns a | ||
* bundle with null route, is when the template could | ||
* not be resolved. It means policies are there, but | ||
* bundle could not be created, since we don't yet | ||
* have the xfrm_state's. We need to wait for KM to | ||
* negotiate new SA's or bail out with error.*/ | ||
if (net->xfrm.sysctl_larval_drop) { | ||
return make_blackhole(net, family, dst_orig); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
Oops, something went wrong.