NetLabel
Subsystems (5)
RFC 3/4 NetLabel
This patch adds IPv4 CIPSO support to NetLabel subsystem. It includes hooks into the core network stack as well as the required NetLabel components.
include/linux/ip.h | 1 include/net/cipso_ipv4.h | 179 +++ include/net/inet_sock.h | 2 net/ipv4/cipso_ipv4.c | 1568 +++++++++++++++++++++++++++++++ net/ipv4/ip_fragment.c | 38 net/ipv4/ip_options.c | 19 net/netlabel/netlabel_cipso_v4.c | 519 ++++++++++ net/netlabel/netlabel_cipso_v4.h | 185 +++ 8 files changed, 2510 insertions(+), 1 deletion(-)
include/linux/ip.h +0 -0
@@ -57,6 +57,7 @@
#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)
+#define IPOPT_CIPSO (6 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_RR (7 |IPOPT_CONTROL)
#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY)
include/net/cipso_ipv4.h +172 -0
172 lines not on this page · raw message
include/net/inet_sock.h +0 -0
@@ -52,7 +52,7 @@ struct ip_options {
ts_needtime:1, ts_needaddr:1; unsigned char router_alert; - unsigned char __pad1; + unsigned char cipso; unsigned char __pad2; unsigned char __data[0]; };
net/ipv4/cipso_ipv4.c +1547 -0
1,547 lines not on this page · raw message
net/ipv4/ip_fragment.c +0 -0
@@ -73,6 +73,11 @@ struct ipfrag_skb_cb
#define FRAG_CB(skb) ((struct ipfrag_skb_cb*)((skb)->cb))
+/* Track critical IP options that must be the same in each fragment. */ +struct ipq_opts {
+ unsigned char *cipso;
+};
+
/* Describe an entry in the "incomplete datagrams" queue. */
struct ipq {
struct hlist_node list;
@@ -97,6 +102,7 @@ struct ipq {
int iif;
unsigned int rid;
struct inet_peer *peer;+ struct ipq_opts opt;
};
/* Hash table. */
@@ -177,6 +183,8 @@ static __inline__ void frag_free_queue(s
if (work) *work -= sizeof(struct ipq); atomic_sub(sizeof(struct ipq), &ip_frag_mem); + if (qp->opt.cipso) + kfree(qp->opt.cipso); kfree(qp); }
@@ -368,6 +376,8 @@ static struct ipq *ip_frag_create(struct
qp->iif = 0; qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
+ qp->opt.cipso = NULL;
+
/* Initialize a timer for this entry. */ init_timer(&qp->timer); qp->timer.data = (unsigned long) qp; /* pointer to queue */ @@ -514,6 +524,34 @@ static void ip_frag_queue(struct ipq *qp if (end == offset) goto err;
+ /* If this is the first packet fragment we have seen then
+ * record any _critical_ options in qp->opt. Otherwise,
+ * verify that the _critical_ options in the current fragment
+ * match with what is stored in qp->opt.
+ */
+ if (qp->fragments != NULL) {
+ if (qp->opt.cipso) {
+ char cipso_len;
+ cipso_len = skb->nh.raw[FRAG_CB(skb)->h.opt.cipso + 1];
+ if (cipso_len != qp->opt.cipso[1] ||
+ memcmp(qp->opt.cipso, + skb->nh.raw + FRAG_CB(skb)->h.opt.cipso,
+ cipso_len) != 0)
+ goto err;
+ }
+ } else if (qp->fragments == NULL && ihl > 20) {
+ if (FRAG_CB(skb)->h.opt.cipso) {
+ char cipso_len;
+ cipso_len = skb->nh.raw[FRAG_CB(skb)->h.opt.cipso + 1];
+ qp->opt.cipso = kmalloc(cipso_len, GFP_ATOMIC);
+ if (qp->opt.cipso == NULL)
+ goto err;
+ memcpy(qp->opt.cipso,
+ skb->nh.raw + FRAG_CB(skb)->h.opt.cipso,
+ cipso_len);
+ }
+ }
+
if (pskb_pull(skb, ihl) == NULL) goto err; if (pskb_trim_rcsum(skb, end-offset))
net/ipv4/ip_options.c +0 -0
@@ -24,6 +24,7 @@
#include <net/ip.h>
#include <net/icmp.h>
#include <net/route.h>
+#include <net/cipso_ipv4.h>
/*
* Write options to IP header, record destination address to
@@ -194,6 +195,15 @@ int ip_options_echo(struct ip_options *
dopt->is_strictroute = sopt->is_strictroute; } }
+#ifdef CONFIG_NETLABEL_CIPSOV4
+ if (sopt->cipso) {
+ optlen = sptr[sopt->cipso+1];
+ dopt->cipso = dopt->optlen+sizeof(struct iphdr);
+ memcpy(dptr, sptr+sopt->cipso, optlen);
+ dptr += optlen;
+ dopt->optlen += optlen;
+ }
+#endif /* CONFIG_NETLABEL_CIPSOV4 */
while (dopt->optlen & 3) {
*dptr++ = IPOPT_END;
dopt->optlen++;
@@ -435,6 +445,15 @@ int ip_options_compile(struct ip_options
if (optptr[2] == 0 && optptr[3] == 0)
opt->router_alert = optptr - iph;
break;+#ifdef CONFIG_NETLABEL_CIPSOV4
+ case IPOPT_CIPSO:
+ if (opt->cipso || cipso_v4_validate(&optptr)) {
+ pp_ptr = optptr;
+ goto error;
+ }
+ opt->cipso = optptr - iph;
+ break;
+#endif /* CONFIG_NETLABEL_CIPSOV4 */
case IPOPT_SEC:
case IPOPT_SID:
default:
net/netlabel/netlabel_cipso_v4.c +510 -0
510 lines not on this page · raw message
net/netlabel/netlabel_cipso_v4.h +181 -0
181 lines not on this page · raw message