Messages in this thread Patch in this message | | | From | Rusty Russell <> | Subject | [PATCH] cleanup patch against 2.4.0-test6-pre9 | Date | Fri, 11 Aug 2000 02:50:32 +1000 |
| |
Hi Linus,
Please apply.
o Fixes double-export of symbols in some configs (me) o Cleans up debug printing (Marc Boucher) o Eliminates a bogus MAC address print for logging (Marc Boucher) o Removes a bogus check in REJECT (me) o Fixes an omitted field in ip_queuing code. (James Morris)
TODO: There's still a race somewhere in the userspace packet queuing code, but, well, that's why it's experimental: if it isn't solved by 2.4.0, no biggie.
TODO: There's a module race, independent of the conntrack code.
Thanks, Rusty. diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_conntrack_tuple.h working-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_conntrack_tuple.h --- linux-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_conntrack_tuple.h Thu Aug 10 02:17:14 2000 +++ working-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_conntrack_tuple.h Thu Aug 10 02:21:25 2000 @@ -62,21 +62,13 @@ } dst; }; -#define IP_PARTS_NATIVE(n) \ -(unsigned int)((n)>>24)&0xFF, \ -(unsigned int)((n)>>16)&0xFF, \ -(unsigned int)((n)>>8)&0xFF, \ -(unsigned int)((n)&0xFF) - -#define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n)) - #ifdef __KERNEL__ #define DUMP_TUPLE(tp) \ -DEBUGP("tuple %p: %u %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", \ +DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \ (tp), (tp)->dst.protonum, \ - IP_PARTS((tp)->src.ip), ntohs((tp)->src.u.all), \ - IP_PARTS((tp)->dst.ip), ntohs((tp)->dst.u.all)) + NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ + NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_queue.h working-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_queue.h --- linux-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_queue.h Wed Apr 12 17:43:06 2000 +++ working-2.4.0-test6-9/include/linux/netfilter_ipv4/ip_queue.h Thu Aug 10 02:25:06 2000 @@ -26,6 +26,10 @@ unsigned int hook; /* Netfilter hook we rode in on */ char indev_name[IFNAMSIZ]; /* Name of incoming interface */ char outdev_name[IFNAMSIZ]; /* Name of outgoing interface */ + unsigned short hw_protocol; /* Hardware protocol (network order) */ + unsigned short hw_type; /* Hardware type */ + unsigned char hw_addrlen; /* Hardware address length */ + unsigned char hw_addr[8]; /* Hardware address */ size_t data_len; /* Length of packet data */ unsigned char payload[0]; /* Optional packet data */ } ipq_packet_msg_t; diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/Makefile working-2.4.0-test6-9/net/ipv4/netfilter/Makefile --- linux-2.4.0-test6-9/net/ipv4/netfilter/Makefile Thu Aug 10 02:17:15 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/Makefile Thu Aug 10 02:20:49 2000 @@ -19,7 +19,8 @@ # Link order matters here. ifeq ($(CONFIG_IP_NF_CONNTRACK),y) -O_OBJS += ip_conntrack_standalone.o $(IP_NF_CONNTRACK_OBJ) +OX_OBJS += ip_conntrack_standalone.o +O_OBJS += $(IP_NF_CONNTRACK_OBJ) else ifeq ($(CONFIG_IP_NF_CONNTRACK),m) MI_OBJS += $(IP_NF_CONNTRACK_OBJ) diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_core.c working-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_core.c Thu Aug 10 02:17:15 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_core.c Thu Aug 10 02:21:25 2000 @@ -660,8 +660,8 @@ } else if (((*pskb)->nh.iph->daddr & htonl(0x000000FF)) == htonl(0x000000FF)) { printk("Should bcast: %u.%u.%u.%u->%u.%u.%u.%u (sk=%p, ptype=%u)\n", - IP_PARTS((*pskb)->nh.iph->saddr), - IP_PARTS((*pskb)->nh.iph->daddr), + NIPQUAD((*pskb)->nh.iph->saddr), + NIPQUAD((*pskb)->nh.iph->daddr), (*pskb)->sk, (*pskb)->pkt_type); } #endif @@ -998,7 +998,7 @@ .tuple.dst.ip; DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n", - IP_PARTS(sin.sin_addr.s_addr), ntohs(sin.sin_port)); + NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port)); ip_conntrack_put(h->ctrack); if (copy_to_user(user, &sin, sizeof(sin)) != 0) return -EFAULT; @@ -1006,8 +1006,8 @@ return 0; } DEBUGP("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n", - IP_PARTS(tuple.src.ip), ntohs(tuple.src.u.tcp.port), - IP_PARTS(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port)); + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port), + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port)); return -ENOENT; } diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_ftp.c working-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_ftp.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_ftp.c Thu Aug 10 02:17:15 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_ftp.c Thu Aug 10 02:21:25 2000 @@ -21,14 +21,6 @@ #define DEBUGP(format, args...) #endif -#define IP_PARTS_NATIVE(n) \ -(unsigned int)((n)>>24)&0xFF, \ -(unsigned int)((n)>>16)&0xFF, \ -(unsigned int)((n)>>8)&0xFF, \ -(unsigned int)((n)&0xFF) - -#define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n)) - static struct { const char *pattern; size_t plen; @@ -111,7 +103,7 @@ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) { - /* tcplen not negative guarenteed by ip_conntrack_tcp.c */ + /* tcplen not negative guaranteed by ip_conntrack_tcp.c */ struct tcphdr *tcph = (void *)iph + iph->ihl * 4; const char *data = (const char *)tcph + tcph->doff * 4; unsigned int tcplen = len - iph->ihl * 4; @@ -142,8 +134,8 @@ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, csum_partial((char *)tcph, tcplen, 0))) { DEBUGP("ftp_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", - tcph, tcplen, IP_PARTS(iph->saddr), - IP_PARTS(iph->daddr)); + tcph, tcplen, NIPQUAD(iph->saddr), + NIPQUAD(iph->daddr)); return NF_ACCEPT; } diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_standalone.c working-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_standalone.c Thu Aug 10 02:17:16 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ip_conntrack_standalone.c Thu Aug 10 02:20:49 2000 @@ -332,7 +332,6 @@ module_init(init); module_exit(fini); -#ifdef MODULE EXPORT_SYMBOL(ip_conntrack_protocol_register); EXPORT_SYMBOL(invert_tuplepr); EXPORT_SYMBOL(ip_conntrack_alter_reply); @@ -346,4 +345,3 @@ EXPORT_SYMBOL(ip_conntrack_expect_related); EXPORT_SYMBOL(ip_conntrack_tuple_taken); EXPORT_SYMBOL(ip_ct_gather_frags); -#endif diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_core.c working-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_core.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_core.c Thu Aug 10 02:17:16 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_core.c Thu Aug 10 02:21:25 2000 @@ -206,7 +206,7 @@ /* FIXME: IPTOS_TOS(iph->tos) --RR */ if (ip_route_output(&rt, var_ip, 0, 0, 0) != 0) { DEBUGP("do_extra_mangle: Can't get route to %u.%u.%u.%u\n", - IP_PARTS(var_ip)); + NIPQUAD(var_ip)); return 0; } @@ -312,7 +312,7 @@ && *var_ipp != orig_dstip && !do_extra_mangle(*var_ipp, other_ipp)) { DEBUGP("Range %u %u.%u.%u.%u rt failed!\n", - i, IP_PARTS(*var_ipp)); + i, NIPQUAD(*var_ipp)); /* Can't route? This whole range part is * probably screwed, but keep trying * anyway. */ @@ -513,8 +513,8 @@ ? " PROTO_SPECIFIED" : "", (mr->range[i].flags & IP_NAT_RANGE_FULL) ? " FULL" : "", - IP_PARTS(mr->range[i].min_ip), - IP_PARTS(mr->range[i].max_ip), + NIPQUAD(mr->range[i].min_ip), + NIPQUAD(mr->range[i].max_ip), mr->range[i].min.all, mr->range[i].max.all); } @@ -715,7 +715,7 @@ *pskb, info->manips[i].maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST", - IP_PARTS(info->manips[i].manip.ip), + NIPQUAD(info->manips[i].manip.ip), htons(info->manips[i].manip.u.all)); manip_pkt((*pskb)->nh.iph->protocol, (*pskb)->nh.iph, @@ -797,7 +797,7 @@ DEBUGP("icmp_reply: inner %s -> %u.%u.%u.%u %u\n", info->manips[i].maniptype == IP_NAT_MANIP_SRC ? "DST" : "SRC", - IP_PARTS(info->manips[i].manip.ip), + NIPQUAD(info->manips[i].manip.ip), ntohs(info->manips[i].manip.u.udp.port)); manip_pkt(inner->protocol, inner, skb->len - ((void *)inner - (void *)iph), @@ -812,7 +812,7 @@ DEBUGP("icmp_reply: outer %s -> %u.%u.%u.%u\n", info->manips[i].maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST", - IP_PARTS(info->manips[i].manip.ip)); + NIPQUAD(info->manips[i].manip.ip)); manip_pkt(0, iph, skb->len, &info->manips[i].manip, info->manips[i].maniptype, diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_ftp.c working-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_ftp.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_ftp.c Thu Aug 10 02:17:16 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_ftp.c Thu Aug 10 02:21:25 2000 @@ -54,13 +54,13 @@ newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; DEBUGP("nat_expected: PORT cmd. %u.%u.%u.%u->%u.%u.%u.%u\n", - IP_PARTS(newsrcip), IP_PARTS(newdstip)); + NIPQUAD(newsrcip), NIPQUAD(newdstip)); } else { /* PASV command: make the connection go to the server */ newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; DEBUGP("nat_expected: PASV cmd. %u.%u.%u.%u->%u.%u.%u.%u\n", - IP_PARTS(newsrcip), IP_PARTS(newdstip)); + NIPQUAD(newsrcip), NIPQUAD(newdstip)); } UNLOCK_BH(&ip_ftp_lock); @@ -69,7 +69,7 @@ else newip = newdstip; - DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", IP_PARTS(newip)); + DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); mr.rangesize = 1; /* We don't want to manip the per-protocol, just the IPs... */ @@ -110,7 +110,7 @@ MUST_BE_LOCKED(&ip_ftp_lock); sprintf(buffer, "%u,%u,%u,%u,%u,%u", - IP_PARTS(newip), port>>8, port&0xFF); + NIPQUAD(newip), port>>8, port&0xFF); tcplen = (*pskb)->len - iph->ihl * 4; newtcplen = tcplen - matchlen + strlen(buffer); diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_rule.c working-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_rule.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_rule.c Thu May 18 18:10:23 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ip_nat_rule.c Thu Aug 10 02:21:25 2000 @@ -226,7 +226,7 @@ = { 1, { { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } } } }; DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n", conntrack, - IP_PARTS(ip)); + NIPQUAD(ip)); return ip_nat_setup_info(conntrack, &mr, hooknum); } diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ip_queue.c working-2.4.0-test6-9/net/ipv4/netfilter/ip_queue.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ip_queue.c Thu Aug 10 02:17:16 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ip_queue.c Thu Aug 10 02:25:06 2000 @@ -4,10 +4,11 @@ * * (C) 2000 James Morris, this code is GPL. * - * 2000-03-27: Simplified code (thanks to Andi Kleen for clues). (JM) - * 2000-05-20: Fixed notifier problems (following Miguel Freitas' report). (JM) + * 2000-03-27: Simplified code (thanks to Andi Kleen for clues). + * 2000-05-20: Fixed notifier problems (following Miguel Freitas' report). * 2000-06-19: Fixed so nfmark is copied to metadata (reported by Sebastian - * Zander). (JM) + * Zander). + * 2000-08-01: Added Nick Williams' MAC support. * */ #include <linux/module.h> @@ -398,6 +399,14 @@ else pm->indev_name[0] = '\0'; if (e->info->outdev) strcpy(pm->outdev_name, e->info->outdev->name); else pm->outdev_name[0] = '\0'; + pm->hw_protocol = e->skb->protocol; + if (e->skb->rx_dev) { + pm->hw_type = e->skb->rx_dev->type; + if (e->skb->rx_dev->hard_header_parse) + pm->hw_addrlen = + e->skb->rx_dev->hard_header_parse(e->skb, + pm->hw_addr); + } if (data_len) memcpy(pm->payload, e->skb->data, data_len); nlh->nlmsg_len = skb->tail - old_tail; diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_LOG.c working-2.4.0-test6-9/net/ipv4/netfilter/ipt_LOG.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_LOG.c Fri May 12 13:22:38 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ipt_LOG.c Thu Aug 10 02:21:35 2000 @@ -288,14 +288,15 @@ if (in && !out) { /* MAC logging for input chain only. */ printk("MAC="); - if ((*pskb)->dev && (*pskb)->dev->hard_header_len) { + if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != iph) { int i; unsigned char *p = (*pskb)->mac.raw; for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++) printk("%02x%c", *p, i==(*pskb)->dev->hard_header_len - 1 ? ' ':':'); - } + } else + printk(" "); } dump_packet(loginfo, iph, (*pskb)->len, 1); diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_MASQUERADE.c working-2.4.0-test6-9/net/ipv4/netfilter/ipt_MASQUERADE.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_MASQUERADE.c Wed Jul 12 17:52:23 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ipt_MASQUERADE.c Thu Aug 10 02:21:26 2000 @@ -92,7 +92,7 @@ } newsrc = rt->rt_src; - DEBUGP("newsrc = %u.%u.%u.%u\n", IP_PARTS(newsrc)); + DEBUGP("newsrc = %u.%u.%u.%u\n", NIPQUAD(newsrc)); ip_rt_put(rt); WRITE_LOCK(&masq_lock); diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_REJECT.c working-2.4.0-test6-9/net/ipv4/netfilter/ipt_REJECT.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_REJECT.c Fri Jul 28 21:36:46 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ipt_REJECT.c Thu Aug 10 02:24:15 2000 @@ -247,11 +247,6 @@ DEBUGP("REJECT: TCP_RESET illegal for non-tcp\n"); return 0; } - /* Only for local input. Rest is too dangerous. */ - if ((hook_mask & ~(1 << NF_IP_LOCAL_IN)) != 0) { - DEBUGP("REJECT: TCP_RESET only from INPUT\n"); - return 0; - } } return 1; diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_limit.c working-2.4.0-test6-9/net/ipv4/netfilter/ipt_limit.c --- linux-2.4.0-test6-9/net/ipv4/netfilter/ipt_limit.c Mon May 1 16:20:45 2000 +++ working-2.4.0-test6-9/net/ipv4/netfilter/ipt_limit.c Thu Aug 10 02:21:26 2000 @@ -15,14 +15,6 @@ #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ipt_limit.h> -#define IP_PARTS_NATIVE(n) \ -(unsigned int)((n)>>24)&0xFF, \ -(unsigned int)((n)>>16)&0xFF, \ -(unsigned int)((n)>>8)&0xFF, \ -(unsigned int)((n)&0xFF) - -#define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n)) - /* The algorithm used is the Simple Token Bucket Filter (TBF) * see net/sched/sch_tbf.c in the linux source tree */ diff -urN -X /tmp/file1l79N2 --minimal linux-2.4.0-test6-9/net/netsyms.c working-2.4.0-test6-9/net/netsyms.c --- linux-2.4.0-test6-9/net/netsyms.c Thu Aug 10 02:17:16 2000 +++ working-2.4.0-test6-9/net/netsyms.c Thu Aug 10 02:20:49 2000 @@ -569,51 +569,6 @@ EXPORT_SYMBOL(nf_getsockopt); #endif -#ifdef CONFIG_IP_NF_CONNTRACK -#include <linux/netfilter_ipv4/ip_conntrack_protocol.h> -#include <linux/netfilter_ipv4/ip_conntrack_helper.h> -#include <linux/netfilter_ipv4/ip_conntrack_core.h> -EXPORT_SYMBOL(ip_conntrack_protocol_register); -EXPORT_SYMBOL(invert_tuplepr); -EXPORT_SYMBOL(ip_conntrack_alter_reply); -EXPORT_SYMBOL(ip_conntrack_destroyed); -EXPORT_SYMBOL(ip_conntrack_get); -EXPORT_SYMBOL(ip_conntrack_module); -EXPORT_SYMBOL(ip_conntrack_helper_register); -EXPORT_SYMBOL(ip_conntrack_helper_unregister); -EXPORT_SYMBOL(ip_ct_selective_cleanup); -EXPORT_SYMBOL(ip_ct_refresh); -EXPORT_SYMBOL(ip_conntrack_expect_related); -EXPORT_SYMBOL(ip_conntrack_tuple_taken); -EXPORT_SYMBOL(ip_ct_gather_frags); -#ifdef CONFIG_IP_NF_FTP -#include <linux/netfilter_ipv4/ip_conntrack_ftp.h> -EXPORT_SYMBOL(ip_ftp_lock); -#endif -#endif /*CONFIG_IP_NF_CONNTRACK*/ - -#ifdef CONFIG_IP_NF_NAT -#include <linux/netfilter_ipv4/ip_nat.h> -#include <linux/netfilter_ipv4/ip_nat_helper.h> -#include <linux/netfilter_ipv4/ip_nat_rule.h> -EXPORT_SYMBOL(ip_nat_setup_info); -EXPORT_SYMBOL(ip_nat_helper_register); -EXPORT_SYMBOL(ip_nat_helper_unregister); -EXPORT_SYMBOL(ip_nat_expect_register); -EXPORT_SYMBOL(ip_nat_expect_unregister); -EXPORT_SYMBOL(ip_nat_cheat_check); -#endif - -#ifdef CONFIG_IP_NF_IPTABLES -#include <linux/netfilter_ipv4/ip_tables.h> -EXPORT_SYMBOL(ipt_register_table); -EXPORT_SYMBOL(ipt_unregister_table); -EXPORT_SYMBOL(ipt_register_target); -EXPORT_SYMBOL(ipt_unregister_target); -EXPORT_SYMBOL(ipt_register_match); -EXPORT_SYMBOL(ipt_unregister_match); -#endif - EXPORT_SYMBOL(register_gifconf); EXPORT_SYMBOL(net_call_rx_atomic); -- Hacking time. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |