When use gre vport, openvswitch register a gre_cisco_protocol but
does not supply a err_handler with it. The gre_cisco_err() in
net/ipv4/gre_demux.c expect err_handler be provided with the
gre_cisco_protocol implementation, and call ->err_handler() without
existence check, cause the kernel crash.
This patch provide a err_handler to fix this bug.
Signed-off-by: Wei Zhang <asuka.com@163.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
struct gre_cisco_protocol {
int (*handler)(struct sk_buff *skb, const struct tnl_ptk_info *tpi);
struct gre_cisco_protocol {
int (*handler)(struct sk_buff *skb, const struct tnl_ptk_info *tpi);
+ int (*err_handler)(struct sk_buff *skb, u32 info,
+ const struct tnl_ptk_info *tpi);
+/* Called with rcu_read_lock and BH disabled. */
+static int gre_err(struct sk_buff *skb, u32 info,
+ const struct tnl_ptk_info *tpi)
+{
+ struct ovs_net *ovs_net;
+ struct vport *vport;
+
+ ovs_net = net_generic(dev_net(skb->dev), ovs_net_id);
+ if ((tpi->flags & TUNNEL_KEY) && (tpi->flags & TUNNEL_SEQ))
+ vport = rcu_dereference(ovs_net->vport_net.gre64_vport);
+ else
+ vport = rcu_dereference(ovs_net->vport_net.gre_vport);
+
+ if (unlikely(!vport))
+ return PACKET_REJECT;
+ else
+ return PACKET_RCVD;
+}
+
static int __send(struct vport *vport, struct sk_buff *skb,
int tunnel_hlen,
__be32 seq, __be16 gre64_flag)
static int __send(struct vport *vport, struct sk_buff *skb,
int tunnel_hlen,
__be32 seq, __be16 gre64_flag)
static struct gre_cisco_protocol gre_protocol = {
.handler = gre_rcv,
static struct gre_cisco_protocol gre_protocol = {
.handler = gre_rcv,
+ .err_handler = gre_err,