linux-stable/include/linux/if_pppox.h
Simon Farnsworth 287f3a943f pppoe: Use workqueue to die properly when a PADT is received
When a PADT frame is received, the socket may not be in a good state to
close down the PPP interface. The current implementation handles this by
simply blocking all further PPP traffic, and hoping that the lack of traffic
will trigger the user to investigate.

Use schedule_work to get to a process context from which we clear down the
PPP interface, in a fashion analogous to hangup on a TTY-based PPP
interface. This causes pppd to disconnect immediately, and allows tools to
take immediate corrective action.

Note that pppd's rp_pppoe.so plugin has code in it to disable the session
when it disconnects; however, as a consequence of this patch, the session is
already disabled before rp_pppoe.so is asked to disable the session. The
result is a harmless error message:

Failed to disconnect PPPoE socket: 114 Operation already in progress

This message is safe to ignore, as long as the error is 114 Operation
already in progress; in that specific case, it means that the PPPoE session
has already been disabled before pppd tried to disable it.

Signed-off-by: Simon Farnsworth <simon@farnz.org.uk>
Tested-by: Dan Williams <dcbw@redhat.com>
Tested-by: Christoph Schulz <develop@kristov.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
2015-03-02 00:17:31 -05:00

98 lines
3 KiB
C

/***************************************************************************
* Linux PPP over X - Generic PPP transport layer sockets
* Linux PPP over Ethernet (PPPoE) Socket Implementation (RFC 2516)
*
* This file supplies definitions required by the PPP over Ethernet driver
* (pppox.c). All version information wrt this file is located in pppox.c
*
* License:
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*/
#ifndef __LINUX_IF_PPPOX_H
#define __LINUX_IF_PPPOX_H
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/ppp_channel.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <uapi/linux/if_pppox.h>
static inline struct pppoe_hdr *pppoe_hdr(const struct sk_buff *skb)
{
return (struct pppoe_hdr *)skb_network_header(skb);
}
struct pppoe_opt {
struct net_device *dev; /* device associated with socket*/
int ifindex; /* ifindex of device associated with socket */
struct pppoe_addr pa; /* what this socket is bound to*/
struct sockaddr_pppox relay; /* what socket data will be
relayed to (PPPoE relaying) */
struct work_struct padt_work;/* Work item for handling PADT */
};
struct pptp_opt {
struct pptp_addr src_addr;
struct pptp_addr dst_addr;
u32 ack_sent, ack_recv;
u32 seq_sent, seq_recv;
int ppp_flags;
};
#include <net/sock.h>
struct pppox_sock {
/* struct sock must be the first member of pppox_sock */
struct sock sk;
struct ppp_channel chan;
struct pppox_sock *next; /* for hash table */
union {
struct pppoe_opt pppoe;
struct pptp_opt pptp;
} proto;
__be16 num;
};
#define pppoe_dev proto.pppoe.dev
#define pppoe_ifindex proto.pppoe.ifindex
#define pppoe_pa proto.pppoe.pa
#define pppoe_relay proto.pppoe.relay
static inline struct pppox_sock *pppox_sk(struct sock *sk)
{
return (struct pppox_sock *)sk;
}
static inline struct sock *sk_pppox(struct pppox_sock *po)
{
return (struct sock *)po;
}
struct module;
struct pppox_proto {
int (*create)(struct net *net, struct socket *sock);
int (*ioctl)(struct socket *sock, unsigned int cmd,
unsigned long arg);
struct module *owner;
};
extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp);
extern void unregister_pppox_proto(int proto_num);
extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
/* PPPoX socket states */
enum {
PPPOX_NONE = 0, /* initial state */
PPPOX_CONNECTED = 1, /* connection established ==TCP_ESTABLISHED */
PPPOX_BOUND = 2, /* bound to ppp device */
PPPOX_RELAY = 4, /* forwarding is enabled */
PPPOX_ZOMBIE = 8, /* dead, but still bound to ppp device */
PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/
};
#endif /* !(__LINUX_IF_PPPOX_H) */